Pi and the Sponza atrium

March 14th, 2010 by Bramz

“you may expect updates soon” means “Look, I’m working on it, but I can’t pull all-nighters anymore. So, it’s going to take a while, OK?” =) So, a mere three weeks after that previous statement, here’s my first real update on the LiAR ray tracer. What have I been doing? Well, I concentrated my efforts on the Sponza atrium, to get this one rendered correctly and fast enough. Although it’s an old challenge, I figured that if I wouldn’t be able to tackle this one, there’s no point in trying more up to date ones. So here’s a list of things improved over the last couple of weeks:

  • Added TriangleMeshComposite which merges the triangle meshes of different objects into one acceleration tree. This is especially important in the Sponza atrium, as the 34 different TriangleMesh objects in the sponza scene largely overlap. So ray traversals are going to hit the bounding boxes of most of them, most of the time, and as such the traversal degrades to a linear search of the scene objects. Using the TriangleMeshComposite, ray traversal visits only one triangle mesh.
  • LightSky caches the radiances in a rasterized map, using the same resolution as the CDF map. This ensures better coherence with the PDFs of the drawn samples (using importance sampling)
  • Using Multiple Importance Sampling for the direct lighting pass solves a lot of the noise issues in the shadows (otherwise, most of the shadow rays are aimed at the sun and thus blocked)
  • Final Gather step uses the local effective estimation radius to decide if secondary gather rays are necessary. Before, it used the global maximum estimation radius, but that one needs to be quite large. So the secondary gather step was triggered a lot, causing either a huge performance hit, or a quality drop. In areas with high photon density, this threshold may be lower as the photon map is much more detailed and the need for second gather rays averted. The rule is now that secondary gathering is only used if the length of the first gather ray is smaller than the effective estimation radius of the photon lookup. Otherwise, it is assued that the first gather step is of sufficient quality.
  • The samplers (Stratifier and LatinHypercube) take into account the pixel super sampling when generating samples for lights, BSDFs, gather rays, … For example, when using 3×3 super sampling with 8×8 gather rays each, the stratifier will generate the gather samples on a (3*8)x(3*8) grid.
  • The shaders now return a BSDF instance, caching the texture lookups. Don’t know why I haven’t done this before, but it surely helps with complex textures …
  • Added JPEG and OpenEXR image codecs
  • Lots of improvements to the Blender exporter, though there’s still lots and lots missing

Here’s a render showing the current state of LiAR. Click on the image for full resolution. Tonemapping has been done in photoshop. Model & textures courtesy of Marko Dabrovic.

Work on a ray tracer is of course never done, and even for this Sponza atrium, there’s still room for improvement, both quality and performance wise. Here’s a bit of a TODO list for the near and far future:

  • Improve final gathering quality, using importance sampling based on the directions of the local photons
  • Use a profiler to investigate how much can be gained by improving the performance of the ray traversals and Kd-tree lookups
  • Use caching and subsampling to improve the perfomance and smoothness of the indirect lighting
  • Add volumetric stuff
  • Spectral rendering. Now I’m using XYZ values everywhere, which is (a) physically wrong and (b) doesn’t allow dispersion
  • Implement subtractive lighting to render objects with an existing backdrop in one pass.
  • Implement the Metropolis Light Transport algorithm

Stay tuned, and happy Pi day!

2 Responses to “Pi and the Sponza atrium”

  1. Kevin Says:

    Wow, the sponza image looks fantastic! Glad to see more progress! :)

  2. bramz Says:

    Thanks. Now I just need to add some volumetric scattering to show the beam of light, and then it’s time to move on to the next challenge …

    I’m also looking into what acceleration structure to use for the triangle mesh. I have a few laying around, and the results are a bit counterintuitive …