|
Post by vityafx on Jun 16, 2022 8:32:06 GMT
Hello everyone. I am writing one in Rust and I am really upset. Since the first chapters I was using the Rust's glm library but then noticed it was old and changed to glam. Now, what has been happening with glam a lot is that it is oriented column-wise rather than row-wise as glm in c++ and in Rust. I had to rewrite all the matrices to support that. Then, the next problem was that I was too lazy to write some matrices like rotation, translation and scaling as I had already known that there was a function in the glam library to just create a matrix out of of a translation/scale vector and same for rotation, so I decided to use those. I did write all the tests from the book and all were passing. Sometimes the tests instead of having `0.0f32` had a very close value to zero, like -2.0444226e-8 and others like that. I don't like that happening but I can't explain why it is happening and is this even a real problem to deal with. Another problem is that sometimes there are precision-wise changes. For example, some tests which want to test a point after some transformation to have a coordinate of -sqrt(2)/2 don't have the exact answer, but just first four digits after the dot sign and others are different. When I change something in the code, these last digits after the first four may also change and I have literally no idea why it could be so. I am confused and frustrated, I wish it was explained in the book, or it just had more tests. Now, the problem I am writing this post about is that once I got to the 7th chapter and got all the tests passing (and via a lot of different transformation, I even rewrote the code to avoid using glam's library transformation in favour of the ones in the book but still the result is not as in the book). The walls in the last paragraph don't show up or show up surprisingly silly, like they were improperly rotated or translated, I don't know. I tried all the possible combinatorics-wise combinations of multiplying matrices, all the ways to create the transformation matrices, all the time the tests are passing, but the behaviour is different and always incorrect (not as in the book). Also weird that the other spheres appear correctly all the time. I went through the book since the transformations chapter like 10 times already and still have no clue what might be wrong here. I am so upset seeing everyone else has it working fine that I am really depressed and want to stop reading the book. Please help me out.
Here is the screenshot:
P.S. The book itself is awesome and I love it.
|
|
|
Post by Jamis on Jun 17, 2022 20:04:24 GMT
This kind of thing is definitely tricky to troubleshoot. I'm not familiar enough with Rust to be able to evaluate your code there, but here's what I'd recommend: - Remove objects from the scene until it is the simplest possible scene that demonstrates the issue. This might mean stripping everything out except the light source and one wall, for instance.
- Choose one pixel from the output that you believe is wrong. (For example, maybe the pixel at 50,50 is black in the output, but you believe it should be something else.)
- Run your ray-tracer on just that pixel. Either use a debugger to step through your ray-tracer, or print state to the terminal. Look for places where it is producing something other than what you expect.
Key to this kind of exercise is question all of your assumptions. Never assume that some value is what you expect it to be. Inspect it! I can't even tell you how often I've chased a bug like this only to discover that a value I had assumed to be correct, wasn't. It's tedious, for sure. My own journey while writing the book involved quite a few of these sessions!
|
|
|
Post by vityafx on Jun 19, 2022 19:07:54 GMT
This kind of thing is definitely tricky to troubleshoot. I'm not familiar enough with Rust to be able to evaluate your code there, but here's what I'd recommend: - Remove objects from the scene until it is the simplest possible scene that demonstrates the issue. This might mean stripping everything out except the light source and one wall, for instance.
- Choose one pixel from the output that you believe is wrong. (For example, maybe the pixel at 50,50 is black in the output, but you believe it should be something else.)
- Run your ray-tracer on just that pixel. Either use a debugger to step through your ray-tracer, or print state to the terminal. Look for places where it is producing something other than what you expect.
Key to this kind of exercise is question all of your assumptions. Never assume that some value is what you expect it to be. Inspect it! I can't even tell you how often I've chased a bug like this only to discover that a value I had assumed to be correct, wasn't. It's tedious, for sure. My own journey while writing the book involved quite a few of these sessions! Thanks a lot for your answer. Though, I had already followed the algorithm you described before, this time I went one by one thing at a time. First, I decided that I need much more performance to see what is exactly behaving wrong in dynamics. I almost knew it was all about rotations but didn't know exactly what it was. I implemented an opengl renderer and parallelised ray intersection algorithm, and added some basic wasd-bindings to translate the camera. This was I could fly inside the test world and see where the light is (by specular reflections) and how rays were calculated and where these walls were and what was going wrong with them.
I noticed that once I was doing that, the rotation was actually done incorrectly, but not with the spheres itself, cuz the code should have worked fine, and I went further. I remembered that we had to perform inverse calculations when hitting objects with rays, by applying an inversed transformation matrix to a ray. Then I remember that I actually didn't implement the rotation of a ray when I was implementing it, as I didn't know how to actually do it! I did scaling, translation and rotation for a point, but felt like with a direction vector it could go wrong. I spent a few hours today figuring out how to do that (not just mathematically, but also considering all the odds of the glam crate for math in Rust I use for this project). Then I implemented it properly and it worked! After that I also revisited my TransformationMatrixBuilder which should always apply transformations in correct order. Now I am almost sure I will never see this issue again!
I must say that dynamic debugging with wasd keys where everything is rendering at 100 fps (at a very small resolution) was very helpful - the moment I saw different specular reflections on two spheres and a correct one on the middle one I knew that the direction of a reflected ray was incorrect and I was right, - I didn't rotate it.
Thanks a lot for the book!
P.S. I also noticed some similar issues to that one which other people have reading this book. If you don't mind an advice, perhaps, it is better to add unit tests for rotation of a ray as well, in the book there are only translation and scaling tests - that way I spent too much time debugging the issue as I was sure everything was tested, but it actually wasn't. I know the book isn't about unit tests, but there are so many tests that I had a false impression that just by reading the book we have already covered all the basic use-cases and so if the tests are passing everything is correct.
|
|
|
Post by Jamis on Jun 20, 2022 0:51:54 GMT
I'm so glad you figured it out! And thank you for the suggestion about the missing test; that definitely feels like an oversight on my part. If the publisher ever wants to do a second edition, I'll keep that in mind!
|
|