Porting a Ray Tracer to Rust, Part 1
willusher.io
willusher.io
There is also a written report with my experience and benchmark results, but unfortunately it's in Portuguese: https://github.com/yuriks/tg-yuriks-2014b/blob/master/final/...
One thing that surprised me a lot is that Rust ended up being noticeably faster than C++ (around 20%) even when compared with clang.
I've found that LLVM is generally faster than GCC and in some cases significantly so.
What do you think about handling the missing `instance` member from DifferentialGeometry by splitting it into two types, PreDifferentialGeometry without this member, and DifferentialGeometry which has two members: the Pre- struct and the instance member?
This way we move the missing `instance` information from the value space to the type space.
If there are significant methods called on both the Pre- and full version of the struct, we can even impl Deref on DifferentialGeometry so that it calls methods on PreDifferentialGeometry automatically.
Generally it's advisable to templatize acceleration structures so they can natively cope with triangles, objects and possibly other primitives (spheres and curves) separately.
In my ray-tracer (Glome), I treat instances as just a container for some other object along with a transformation matrix, that itself behaves like a regular object. Every kind of object has a method to construct a bounding box, so that when building an acceleration structure that contains instances, if I remember correctly, I take the 8 corners of the bounding box of the contained object, transform them, and constructs a new bounding box around the transformed points. It's not optimal, but it works okay.
Another way of working around your problem is to just pass the current instance (or a list of instances) as an argument to your ray intersection function. (I use a similar trick for textures, and also for a tagging scheme where I can apply arbitrary tags to objects and then pass back a list of all the tags of objects that the ray hit when I return a ray intersection.)
Sending the instance to the geometry to fill it out in the struct is a good idea, if Rust had default parameter support I'd do this and have the instance's intersect just default to None and pass itself to the geometry's intersect. Then the functions would have the same signature and we could mark the case of a None instance in geometry as unreachable.
I'm not sure if Rust has something similar to placement new, but I'm sure custom allocators (for memory arenas) are possible in Rust.
http://www.amazon.com/Physically-Based-Rendering-Second-Edit...
To my ears, "Physically Based Rendering" does sound a little stilted. I don't immediately have an intuitive grasp of what it means based on words alone.
It doesn't sound like it means "physics based rendering", which would mean "a rendering process that uses physics at its core."
Rather, the attachment I have to the word "physically" is more along the lines of "metaphorical vs. physical" (i.e. "concrete", "real", "observable"). So along those lines, my natural understanding of "Physically based" rendering would be a process not based on abstract mathematical principles, but one that tries to take the physical properties of objects into account. So, maybe to render a rock you'd think about what it's made of, if moss grows on it, etc.
(I don't know if that's actually what PBR means, just that's what it sounds like to me as a native speaker.)
If you are looking for a good (you can build your own ray tracer) but not too hostile intro to physics based rendering I recommend "Advanced Global Illumination" by Dutre and others (http://www.amazon.com/Advanced-Global-Illumination-Second-Ed...). It is actually quite a fascinating computer science application, and you can produce beautiful images with it.
In conventional (uni-directional) path tracing, rays are shot from the camera only, and bounce around the scene (other than for light visibility testing).
Bi-directional path tracing uses rays originating at both the camera and light sources going in opposite directions.
VCM is a combination of Bi-directional path tracing and photon mapping.
have a look at this link: https://support.solidangle.com/display/AFMUG/Standard