Volumetric light



The volumetric light effect is based on a simple ray-casting equation. The light consists of a number of rays. Each ray runs from the lights origin along its given direction until it either hits an object or its intensity has fallen below a certain threshold. In Meshuggah the object is a text on the x/y plane. It would be way to computationally expensive to have actual geometry for the text. The ray/triangle hit tests would take up too much time considering the number of rays we're using and the number of triangles required for high quality text glyphs. The text will be a bitmap mask instead, representing the rectangular area [ ( -1, -1 ), ( 1, 1 ) ] of the x/y plane. This way we only need a ray/plane hit test per ray.


Simplified ray/plane hit test for x/y plane


If a ray hits the x/y plane within [ ( -1, -1 ), ( 1, 1 ) ] then the corresponding pixel value from the bitmap mask determines whether the ray hit a glyph or not.

To solve z-sorting problems we need to render the volumetric light effect in three steps.

  1. For each ray, draw the part from the origin of the light to its intersection point with the x/y plane. At the intersection point the ray's intensity is set to one by traveled ray length. Another distance based attenuation function can be used as well.

  2. Blend the bitmap mask onto the result of the last render step.

  3. For each ray that didn't hit a text glyph, draw the part from its intersection point with the x/y plane to infinity.

Note that for the third step in order to compensate sudden changes in the result of a ray/plane hit test we store eight bit values in our bitmap mask, zero being ray hits and 255 being ray doesn't hit. This allows us to gradually fade the ray when it comes close to a glyph by multiplying this value to the ray's intensity. Alpha blending is turned on when rendering the rays. Both source and destination blend factor are set to one. Smooth ray edges can be achieved by applying a 1D gradient texture (black - white - black).

The vertex and pixel shader are simple and straightforward. 1D texture coordinate and ray color (the intensity is already pre-multiplied at this point) are copied in the vertex shader. In the pixel shader the interpolated ray color is modulated on the color fetched from the 1D gradient texture and set to the final output color register r0.


Last update on 2002-03-17


Meshuggah Demo and Effect browser.
Copyright 2001, 2002 Carsten Wenzel.
All rights reserved.