|
Post by klomeli on Nov 13, 2021 15:13:12 GMT
I am trying to track down a bug in my code in ch11. I rendered the scene in the section *before* the Fresnel Effect as described by Jamis in his post forum.raytracerchallenge.com/post/438/thread to verify that I was on track. After pouring over posts in this forum relating to ch11 (thank you all, I caught some issues myself through these posts), I am left with something I haven't been able to track down. The first attachment ( before_fresnel_complete_scene.png) is what I get when I render the scene in the book (I have not yet implemented the schlick function). It looks as if my sphere is exhibiting some acne. I simplified the scene to try to track things down a bit by removing the hollow sphere as seen in before_fresnel_partial_scene.png. I don't expect anyone to pour through my code. However, if you have a hunch as to what I should look into, any help would be greatly appreciated. Also if you feel the need to look at the code, here is the public repo: github.com/kyllerss/ray-tracer . The file that sets up the environment is ch11.rs (build_example_3). Thanks in advance for any tips! -Kyle PS. Thank you, Jamis, for this great book! I'm using it to learn Rust and have been having a great time! I'm looking forward to any similar test-driven books you have planned! Attachments:
|
|
|
Post by Jamis on Nov 15, 2021 15:30:04 GMT
Hello klomeli! Looking at your images, it doesn't look like an acne issue to me (which manifests as random specks or noise--usually black--in your image). Are your tests all passing? (Specifically, the test on page 159, "shade_hit() with a transparent material".) I've looked briefly at your code and couldn't see anything obviously wrong, but it looks (from your images) like your reflections are being added too many times (or something). So, I'd start by making sure your tests are passing. If they are all passing, and you're still getting this visual result, I'd recommend using your second image (without the nested sphere) and render just a single pixel from it (where the sphere is too bright). Look at the colors coming back from shade_hit at each point of intersection. If any of them have components that are greater than 1, that's a red flag that something's off. Sorry I can't be more help! - Jamis
|
|
|
Post by klomeli on Nov 15, 2021 17:29:31 GMT
Some additional sample points that indicate that my refraction (not reflection) is the issue. The first attachment is that modified scene using reflective only. This reflection-only view looks fine to me. The second one is what happens when I add refractive glass (still without the inner hollow sphere). I am not convinced any more that this is an "acne" problem, as much as it is refractive rays going haywire when dealing with far off horizon reflection - at least it seems that way to me. Any suggestions as to what to focus look into would be much appreciated. Thanks! Attachments:
|
|
|
Post by klomeli on Nov 15, 2021 17:31:49 GMT
Just saw your reply, Jamis right after I posted my follow-up. Thanks for the pointers. All my tests are passing. I'll begin working tracing what is going on through a single pixel using your suggestions. Thanks again!
|
|
|
Post by klomeli on Nov 19, 2021 17:04:43 GMT
This is turning out be trickier than I anticipated. Part of the problem is that I am not entirely sure what really should be the correct behavior. I have attached the image I am using to troubleshoot the issue. This is the same scene described previously in this thread (without the hollow inner sphere and I made the sphere 0.5 reflective to better visualize the color decay after each iteration). I have selected pixels x:148, y: 159 (close to the center of the image on one of the grey artifacts that should be very close to black). In the event someone wants to take a peek, I created a branch with the current logging instrumentation (https://github.com/kyllerss/ray-tracer/tree/refraction_bug). It's clear to me that a ray stops bouncing around once the remaining iterations reach 0; as the call stack unwinds, the surface color is diminished by the reflective and transparency scalars until it ends up with the grey color (0.2539, 0.2539, 0.2539). [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] Rendering pixel (148, 159)... [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 4) -> down the rabbit hole! [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 4) -> calling color_at [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 3) -> down the rabbit hole! [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 3) -> calling color_at [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 2) -> down the rabbit hole! [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 2) -> EOL - Black [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 2) -> EOL - Black [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 2) -> total: (0.13052385, 0.13052385, 0.13052385), surface: (0.13052385, 0.13052385, 0.13052385), reflected: (0.0, 0.0, 0.0), refracted: (0.0, 0.0, 0.0) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 3) -> returning (0.11747146, 0.11747146, 0.11747146) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 3) -> calling color_at [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 2) -> down the rabbit hole! [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 2) -> calling color_at [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 1) - NO INTERSECTIONS - Black [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 2) -> returning (0.0, 0.0, 0.0) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 2) -> calling color_at [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 1) -> down the rabbit hole! [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 1) -> calling color_at [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 0) -> down the rabbit hole! [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 0) -> EOL - Black [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 0) -> EOL - Black [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 0) -> total: (0.73201996, 0.73201996, 0.73201996), surface: (0.73201996, 0.73201996, 0.73201996), reflected: (0.0, 0.0, 0.0), refracted: (0.0, 0.0, 0.0) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 1) -> returning (0.65881795, 0.65881795, 0.65881795) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 1) -> calling color_at [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 0) -> down the rabbit hole! [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 0) -> EOL - Black [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 0) -> EOL - Black [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 0) -> total: (0.0, 0.0, 0.0), surface: (0.0, 0.0, 0.0), reflected: (0.0, 0.0, 0.0), refracted: (0.0, 0.0, 0.0) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 1) -> returning (0.0, 0.0, 0.0) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 1) -> total: (0.65881795, 0.65881795, 0.65881795), surface: (0.0, 0.0, 0.0), reflected: (0.0, 0.0, 0.0), refracted: (0.65881795, 0.65881795, 0.65881795) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 2) -> returning (0.65881795, 0.65881795, 0.65881795) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 2) -> total: (0.32940897, 0.32940897, 0.32940897), surface: (0.0, 0.0, 0.0), reflected: (0.32940897, 0.32940897, 0.32940897), refracted: (0.0, 0.0, 0.0) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 3) -> returning (0.32940897, 0.32940897, 0.32940897) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 3) -> total: (0.28217596, 0.28217596, 0.28217596), surface: (0.0, 0.0, 0.0), reflected: (0.16470449, 0.16470449, 0.16470449), refracted: (0.11747146, 0.11747146, 0.11747146) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFRACTED (remaining 4) -> returning (0.25395834, 0.25395834, 0.25395834) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 4) -> calling color_at [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 3) - NO INTERSECTIONS - Black [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] REFLECTED (remaining 4) -> returning (0.0, 0.0, 0.0) [2021-11-19T16:51:30Z TRACE ray_tracer::domain::world] COLOR_AT (remaining 4) -> total: (0.25395834, 0.25395834, 0.25395834), surface: (0.0, 0.0, 0.0), reflected: (0.0, 0.0, 0.0), refracted: (0.25395834, 0.25395834, 0.25395834) [2021-11-19T16:51:30Z DEBUG ray_tracer::domain::world] Final color: Color { red: 0.25395834, green: 0.25395834, blue: 0.25395834 }
When reviewing the debug output, it seems to me that the problem lies in COLOR_AT (remaining 1) where the ambient color comes back contributing to the weight of the pixel color, but I am at a loss to explain why that would be a problem. If anyone could suggest how I should be thinking of the behavior at this pixel (or additional output that would be helpful to include), I would greatly appreciate it! PS. For the record, a similar trace Jamis provided in a previous post against a test pixel (pixel x:125, y:125) didn't highlight any issues - that test pixel in my implementation behaves fine. Attachments:
|
|
|
Post by Jamis on Nov 20, 2021 23:04:49 GMT
Well, I'd say the attached image actually looks correct, compared to the one you posted previously where the white was too strong. I wonder if you've managed to fix the bug as a side-effect of investigating it?
|
|
|
Post by klomeli on Nov 21, 2021 21:30:00 GMT
This image is basically the same image minus the inner hollow sphere (I did change reflectivity to 0.5, so that accounts for the toned down effect). Perhaps I need an actual glass sphere to compare my rendering to real world results! 😂 I would have assumed that the small reflection of the checkered background was a problem. Am I expecting the wrong thing?
My next course of action is to download someone else's project to print out some output at the affected pixels to see if that helps me identify where things are going wrong.
|
|
|
Post by Jamis on Nov 22, 2021 16:21:07 GMT
klomeli, it just registered (I know, I'm slow sometimes) that you said this is *before* implementing Fresnel/Schlick. The YAML file as given in the link you referenced is uses material settings that assume you've implemented the schlick approximation. If you haven't, then high reflectivity will not be weighted correctly, and you'll wind up with the overexposed look in your original image. My advice would be to assume that since your tests are all passing, you're on the right track, and to forge ahead and implement the schlick approximation. I suspect (given that your render looks otherwise correct) that you'll see everything turn out well. Sorry I missed that earlier! It's my fault for reading too fast. - Jamis
|
|
|
Post by klomeli on Nov 23, 2021 14:09:09 GMT
LOL! Taking your advice I went ahead and implemented the schlick functionality and lo' and behold, all is good! Thanks for the follow-up (and no worries - your personal time spent in the forums is much appreciated!). I was just about to go down an even deeper rabbit hole instrumenting other people's code. I may have said this before, but I really wanted to thank you again for this book. This is exactly what I was looking for to recover from burn-out and an excuse to learn a new language. Thanks! Here is what my scene now looks like. Attachments:
|
|