More specifically: prior to this, SurfaceLights returned the
shadow ray direction vector to use. That was fine, but it
kept the responsibility of generating proper offsets (to account
for floating point error) inside the lights.
Now the SurfaceLights return the world-space point on the light
to sample, along with its surface normal and error magnitude.
This allows the robust shadow ray generation code to be in one
place inside the renderer code.
The main change is that SurfaceClosures now have the hero
wavelength baked into them. Since surface closures come from
surface intersections, and intersections are always specific to
a ray or path, and rays/paths have a fixed wavelength, it doesn't
make sense for the surface closure to constantly be converting
from a more general color representation to spectral samples
whenever its used.
This is also nice because it keeps surface closures removed from
any particular representation of color. All color space handling
etc. can be kept inside the shaders.
They are now generated by a build.rs script from nothing but the
colorspace's primaries, which makes it super easy to add more
colorspaces. So easy that I added three more: ACES AP0, ACES AP1
and Rec.2020.
This lays the foundation for supporting output to different
colorspaces.
This is more a piece-of-mind thing than anything else. But it
also lets us make the number of LDS dimensions lower without
worrying, which in turn makes the code smaller.
After implementation, it does appear to make rendering slower
by a noticable bit compared to what I was doing before. At very
low sampling rates it does provide a bit of visual improvement,
but by the time you get to even just 16 samples per pixel its
benefits seem to disappear.
Due to the slow down and the minimal gains, I'll be removing
this in the next commit. But I want to commit it so I don't
lose the code, since it was an interesting experiment with
some promising results.
Specifically, LightPath is now significantly smaller, and
resultingly faster to process.
Also finally fixed the bug where without light sources the light
from the sky wouldn't affect surfaces.
Also created a proper World struct in the process, to store all
infinite-extent type stuff.
Note that I goofed and did a new rustfmt pass but forgot to
commit before making these changes, so there's a lot of
formatting changes in this too. *sigh*
The lighting is super crappy, and pretty much hacked in. Will
need to redo this properly soon. However, this verifies that
certain other parts of the code are (mostly) working properly.
The part of the renderer responsible for light transport has been
split out into a LightPath struct. Also moving over to spectral
rendering, although it's a bit silly at the moment.
BVH traversal still happens in local space, but final actual
surface intersection calculations are done in world space by
transforming the triangle into world space. This is to improve
numerical consistency between intersections.
Includes:
- More scene parsing code. Making good progress!
- Making the rendering code actually use the Scene and Assembly
types.
- Bare beginnings of a Tracer type.
Everything is done with indices anyway, so there was no reason
for it to store an internal reference to the object data. This
gets rid of the type parameter and lifetime parameter on the BVH
struct itself, which will also make it easier to bundle it with
the data it indexes, which will be important later on.