Monday, 25 October 2010

Light volume sampling

With Bluestone now running nicely under SlimDX I've turned my attention back to light volumes. After seeing how well the technique worked on the sponza scene I've decided to go with volumes over lightmaps for the project I have in mind.

The issue I've been looking at recently is how best to sample a light volume for a scene containing angled or curved geometry. This wasn't an issue with the sponza scene as it fit nicely inside a rectangular volume, it was enough to simply sample the scene at the centre of each light volume texel.

However, you quickly run into trouble with scenes containing curved or angled geometry. You can see in the image below that if we simply sample each volume texel centre we'll end up sampling “outside” the scene. This often leads to streaks and blotches and ends up looking pretty naff.

The problem is exacerbated by linear texture filtering when sampling the light volume. Incorrectly sampled volume texels can adversely affect their correctly sampled neighbours. It's identical to the problem caused by incorrectly padding lightmap textures, only now the problem is in three dimensions.

Overcoming sampling and linear filtering issues

The above two images show a cross section of a light volume texture. Imagine the red line is a wall, on one side the lighting values are dark, on the other, the light volume texels are not occluded and are now lit by the sky. The dots show the location of each sample. The image on the left looks fine, the geometry is completely covered by valid samples, on the right, we're already in trouble.

 Let's see what happens when the texture is filtered during lookup.

The light volume is leaking all over the place. If we were to view the scene in game the interior wall would have a noticeable blue glow but how do you fix that? In a lightmap it's fairly easy, you just copy and expand the border pixels of each UV chart. In a light volume though it's a bit harder.

In short, the way I've overcome the issue is to move the sample location of any invalid samples.

With the invalid samples moved to valid locations the light leaks have been removed. What constitutes an invalid sample and where to then move it is the topic of a whole other blog post :) But to wrap things up, here are some before and after shots. The lighting and AO for this scene was rendered in Bluestone in about 15 seconds. Direct light and AO are rendered into lightmaps, indirect light is rendered into the light volume.

Sample positions left untouched:

Sample positions fixed:

Another example (click for fullsize)


Martin said...


A really interesting blog post as always, thanks for sharing.

It would be interesting to see shots of fixed and unfixed sample positions taken from the same camera position. I'm struggling to see the difference unfortunately.

I had previously thought of a fix for this problem where instead of moving the sample I consider a texel's neighbours in the visibility function, that is, if any of my neighbours can see the light, so can I. Therefore the row of sample behind the wall will also receive illumination making interpolation a non issue. (and perhaps more physically correct that moving the sample??)


Stefan Kamoda said...

Hi Martin,

The issue presents itself as black splotches in the shadowed regions of the un-corrected images. It's no show stopper but the artifact is pretty ugly. I'll post some untextured, volume light only shots which should be a bit clearer.

Your solution sounds perfect for evaluating direct light but I don't think it's suitable for final gather. Which is what I'm doing here although I failed to mention that in the post!


Post a comment