|
Post by newgraphics on Jul 7, 2020 13:34:00 GMT
Hello. I'm really enjoying the book. Currently finishing up the Reflection and Refraction chapter. Would like to reproduce the "before Fresnel" and "after Fresnel" pictures on page 159 (PDF version). Would it be possible to post description of the scene, including materials and light information? Thanks!
|
|
|
Post by Jamis on Jul 8, 2020 16:09:59 GMT
Hello! I'm glad to hear you're enjoying the book. Here's a YML scene description of the image you mentioned: # Scene description for image on page 159 of # "The Ray Tracer Challenge", depicting two nested # glass spheres against a checkered background. # # author: Jamis Buck <jamis@jamisbuck.org>
- add: camera width: 600 height: 600 field-of-view: 0.45 from: [ 0, 0, -5 ] to: [ 0, 0, 0 ] up: [ 0, 1, 0 ]
- add: light intensity: [ 0.9, 0.9, 0.9 ] at: [ 2, 10, -5 ]
# wall - add: plane transform: - [ rotate-x, 1.5708 ] - [ translate, 0, 0, 10 ] material: pattern: type: checkers colors: - [ 0.15, 0.15, 0.15 ] - [ 0.85, 0.85, 0.85 ] ambient: 0.8 diffuse: 0.2 specular: 0
# glass ball - add: sphere material: color: [ 1, 1, 1 ] ambient: 0 diffuse: 0 specular: 0.9 shininess: 300 reflective: 0.9 transparency: 0.9 refractive-index: 1.5
# hollow center - add: sphere transform: - [ scale, 0.5, 0.5, 0.5 ] material: color: [ 1, 1, 1 ] ambient: 0 diffuse: 0 specular: 0.9 shininess: 300 reflective: 0.9 transparency: 0.9 refractive-index: 1.0000034
It's not EXACTLY the same image from the book (the light source is in a different position, for one thing; I must have done some fiddling with the file after producing the image for the book), but it's close. Running it just now on my reference implementation, it produces the following image: I hope that helps!
|
|
|
Post by newgraphics on Jul 13, 2020 0:25:33 GMT
Thank you Jamis! My render looks very similar:
BTW, the 300x300 render completes in about 8 minutes. I'm using Python and have not done any code optimization. I did use multiprocessor library (on 12 cores). Does 8 minutes for this image sound too slow?
|
|
|
Post by Jamis on Jul 13, 2020 19:10:23 GMT
That looks great! As for 8 minutes, that seems a bit on the long side. My Ruby version renders the 300x300 image in 24 seconds. Mine is somewhat optimized, but there's quite a bit of optimizations that could yet be done. I'm curious where your renderer is spending most of that time.
|
|
|
Post by newgraphics on Jul 14, 2020 17:23:19 GMT
>> My Ruby version renders the 300x300 image in 24 seconds
Wow! I'm glad I asked . Are you using any kind of parallel processing?
>> I'm curious where your renderer is spending most of that time.
Me too. I'll have to figure out how to do profiling in Python and will post here the results. I should have started the profiling stuff earlier, but the book is so interesting that I don't want to take any detours!
Also, I'm guessing that my renderer is so slow because Python is an interpreted language.
|
|
|
Post by Jamis on Jul 15, 2020 2:28:06 GMT
> Are you using any kind of parallel processing?
Yeah, that 24s render was done with six processes running in parallel. The biggest wins generally come from caching the results of matrix inversions, though. Are you caching your inverted matrices? If not, that's probably some low-hanging fruit that can really make a big difference.
> Also, I'm guessing that my renderer is so slow because Python is an interpreted language.
That can be part of it, but Ruby is interpreted, too, and that's where I got the 24s render. With the right optimziations, and the worst bottlenecks removed, I would expect Python to run pretty quick.
Good luck! Let me know how it goes.
- Jamis
|
|
|
Post by newgraphics on Jul 15, 2020 23:07:23 GMT
>> The biggest wins generally come from caching the results of matrix inversions Yes, that's exactly what the profiler showed. After caching matrix inversion in shapes, I got 55 seconds for the 300x300 image. Replacing the self-made matrix inversion with built-in (from python numpy library) reduced the time to 27 seconds, but that would be cheating The next bottleneck (according to the profiler) is multiplying matrix by a vector, although I don't see how that could be improved. Perhaps reducing float precision. But I'm not trying to write the world's fastens renderer. It's fast enough for me Thanks again for a the wonderful book! I hope you are secretly working on another programming challenge book.
|
|
|
Post by Jamis on Jul 16, 2020 3:31:48 GMT
Yay! I'm glad that helped. And it's never cheating if it works. As for another book, I've got a few ideas I've been tossing around, but nothing has gelled yet. So don't hold your breath!
|
|
|
Post by sbphillips on Jul 17, 2020 21:45:10 GMT
Hey newgraphics, is your code available for review? I'm just learning Python and would like to see what you did and your speed improvements.
Thanks, Steve
|
|
|
Post by newgraphics on Jul 19, 2020 20:34:01 GMT
Hi Steve. My code is still work in progress I have seen Python code from another user on this forum who very kindly posted his Python code on github. It's much better than what I have right now. Here is his post: forum.raytracerchallenge.com/post/650
As far as speed improvements, I did set a separate class attribute for inverse matrix in Shape. Otherwise, the tracer would have to do the very expensive inverse matrix calculation of the same matrix for each ray intersection. This optimization takes just a couple of lines of code and gives you 5+ times speed improvements.
|
|
|
Post by disembleergon on Aug 9, 2021 14:42:16 GMT
Hi! I tried to exactly recreate the scene in my C++ Ray Tracer, but something seems off... What could be the problem? (I added the schlick function already)
|
|
|
Post by Jamis on Aug 9, 2021 16:03:03 GMT
Hey disembleergon, welcome! My guess, judging from your picture, is that either your sphere or your plane is not being transformed correctly. The sphere should sit wholly in front of the plane, but it looks like the plane is probably cutting your sphere in half for some reason.
|
|
|
Post by disembleergon on Aug 10, 2021 8:48:17 GMT
Thank you! I solved the problem by changing the order of multiplying the translation and rotation matrix ;D Now I have another problem: My sphere is completely black with some small reflections now and I haven't changed anything on the materials....
|
|
|
Post by Jamis on Aug 10, 2021 15:04:46 GMT
It seems like there was some hint of that black in your original picture, too, with that black ring in the middle. I wonder if the material on your inner sphere is not quite right? Can you try removing the outer sphere and rendering the scene without it, to see what the inner sphere renders like?
|
|
|
Post by disembleergon on Aug 13, 2021 17:32:19 GMT
Hi Jamis, here's the hollow sphere only: and here's the glass sphere only: As you can see, both of them are fully black... Here's the code: (ReflactiveIndex::glass = 1.5)World w{}; Plane wall{}; wall.setTransform(translation(0, 0, 10) * rotate_x(1.5708)); SolidPattern clrA{Color{0.15, 0.15, 0.15}}; SolidPattern clrB{Color{0.85, 0.85, 0.85}}; CheckersPattern checkers{makePattern_ptr<SolidPattern>(clrA), makePattern_ptr<SolidPattern>(clrB)}; wall.material.pattern = makePattern_ptr<CheckersPattern>(checkers); wall.material.ambient = 0.8; wall.material.diffuse = 0.2; wall.material.specular = 0; w.addShape<Plane>(wall); Sphere glassSphere{}; Material glass{}; glass.color = Color{1, 1, 1}; glass.ambient = 0; glass.diffuse = 0; glass.specular = 0.9; glass.shininess = 300; glass.reflective = 0.9; glass.transparency = 0.9; glass.refractive_index = RefractiveIndex::glass; glassSphere.material = glass; w.addShape<Sphere>(glassSphere); Material hollow{}; hollow.color = Color{1, 1, 1}; hollow.ambient = 0; hollow.diffuse = 0; hollow.specular = 0.9; hollow.shininess = 300; hollow.reflective = 0.9; hollow.transparency = 0.9; hollow.refractive_index = 1.0000034; Sphere hollowSphere{}; hollowSphere.setTransform(scaling(0.5, 0.5, 0.5)); hollowSphere.material = hollow; w.addShape<Sphere>(hollowSphere); w.light = PointLight{point(2, 10, -5), Color{0.9, 0.9, 0.9}}; Camera cam{600, 600, .45}; cam.setTransformation(view_transform(point(0, 0, -5), point(0, 0, 0), vector(0, 1, 0))); w.render(cam).toPPM("C:\\Users\\tompe\\desktop\\scene.ppm");
|
|