markf
New Member
Posts: 12
|
Post by markf on Mar 18, 2019 19:50:21 GMT
Hi everyone, My first post, so I'd like to say how interesting and challenging this book has been. This forum has been a helpful resource as well. I stumbled upon the Ray Tracer Challenge in September when looking for a project that would help sharpen my APL programming skills. I've managed to work through all but the chapter on CSG, but I have a strange problem with reflection and transparency. When each attribute is used alone in an object within a scene, all renders well. However when an object has both reflective and transparent qualities, the object ends up being rendered without transparency. All of the tests in Chapter 11 pass, and I can find no errors when reviewing the code. Here are some pictures to illustrate the problem. The first is the air sphere within a glass sphere, with both having a reflective value of zero and a transparency value of one. The second shows the inner sphere with a reflective value of 0.9 and the third shows both spheres with a value of 0.9 for reflection. The scene for Chapter 11 taken from the image gallery renders correctly except that the two glass spheres are solid in color. Any suggestions on where I might start looking for the problem? Thanks, ~Mark
|
|
|
Post by hokiecsgrad on Mar 18, 2019 23:27:45 GMT
It kind of looks like your Fresnel Effect code might not be working perfectly? I'd maybe check your ShadeHit function and make sure the schlick() function is getting called properly?
|
|
markf
New Member
Posts: 12
|
Post by markf on Mar 19, 2019 2:20:25 GMT
Good thought! I'll try just returning surface+reflective+refractive in shade_hit to see what result I get.
|
|
markf
New Member
Posts: 12
|
Post by markf on Mar 19, 2019 22:08:47 GMT
Well, the schlick() calculation was not at fault. While going through the various functions I've written and comparing them to the book (p1.0 release) pseudo-code and pseudo-code files, I haven't been able to find a description of how the lighting() function uses the in_shadow parameter. I suppose I'll need to go back to an earlier PDF book copy to find out if that is implemented correctly. I seem to get a correct Chapter 11 rendered scene if I set the reflective value to zero for the two glass balls. Good enough, I guess!
|
|
|
Post by ascotti on Mar 19, 2019 23:26:22 GMT
Hi, the scene looks great indeed but it's probably worth spending a bit more time investigating the issue. The code should compute both the reflected and the refracted colors, then schlick() will sort of "balance" the two: reflected color is weighted by reflectance, and refracted color is weighted by (1-reflectance). If transparency "disappears" then reflectance is 1 or close to 1. The total internal reflection code may be triggering it? If it helps, I have rendered the scene with hardcoded values for the schlick() function to give an idea of the blend between reflection and refraction. Here schlick() always returns 0.2, so mostly transparent: Here 0.5: And finally 0.8, so mostly reflective:
|
|
markf
New Member
Posts: 12
|
Post by markf on Mar 20, 2019 1:52:29 GMT
Thanks for the encouragement and examples shown. I've reviewed the code multiple times and placed the usual debug stop in render to view pixel areas of interest. I couldn't see anything amiss, though I may take a different approach to implementing recursion limits. The schlick values I sampled were mostly small but I didn't view a great deal of data. I did see shadowed mostly true which is why I was curious about its use in lighting. I guess I could try dumping more data for analysis!
~Mark
|
|
markf
New Member
Posts: 12
|
Post by markf on Mar 21, 2019 0:54:07 GMT
Success! The problem indeed lay with the way I was trying to limit recursion. It seems under certain conditions the reflection component of an object's color would be calculated but not the transparency component due to an early termination of the recursion chain. So the call chain would be color_at() -> reflected_color() -> color_at() -> ... reflected_color() terminate Naturally the fix comes with a speed penalty, so it's definitely time to start on some of ascotti's performance improvements! ~Mark BTW, if anyone is interested, the ray tracer was developed in Dyalog APL in a Jupyter notebook. you can find the code at github.com/mafleming/RayTracerChallenge(Please ignore some of my griping about Jamis changing things around from Chapter to Chapter!)
|
|
|
Post by Jamis on Mar 21, 2019 3:12:12 GMT
Haha! I'm always up for a good gripe. The render looks great. I'm glad you figured out what the problem was!
|
|
|
Post by ascotti on Mar 21, 2019 23:46:22 GMT
Ha, good catch... scene looks perfect now! :-) I very much like the notebook, I'm slowly going thru it and trying to figure out the secret behind all the symbols! :-)
|
|
markf
New Member
Posts: 12
|
Post by markf on Mar 22, 2019 3:27:36 GMT
Jamis: Thanks for an excellent book and a great exercise in mastering a new programming language and its unique approach to problem solving. Nothing like it! I gripe a bit about the iterative approach to developing the ray tracer code model, but that's more a critique of a pedagogical approach vs. design modeling approach to the problem. Very effective, if somewhat annoying I will consider the design element beforehand though when I attempt to rewrite this in object-oriented APL. ascotti: I've found your many posts very helpful in places where I've been stuck. The performance ideas were interesting, so I just tried the pre-computed transform matrix suggestion. Perhaps its a tribute to APL array processing, but the change only resulted in about a 13% reduction in rendering time (19 minutes vs. 17 minutes for the 800x600 scene posted earlier). Multi-threading might be a better route to improvement. If you're tempted to have a go at APL then be warned; you'll have to manage to persist past the six month mark if you have a hope of getting a grasp of its way of thinking. Reminds me of quitting smoking many years ago! ~Mark
|
|