volumetric light

zhugel_007

Newcomer
Hi,

I would like to implement volumetric light.

I have found following methods:

1. shadow map + sampling plane.
(http://ati.amd.com/developer/gdc/mitchell_lightshafts.pdf)
(http://nis-ei.eng.hokudai.ac.jp/~doba/papers/pg00.pdf)
(ShaderX3)

2. ray tracing based
(Nvidia SDK 10.5)

3. image process based
(GPU Gem 3)
(ShaderX6)

But they all have limits:

1. when you go close to the light volume:
- you can see the sampling planes
- framerate goes down quickly

2. slow in large unit

3. light beam disappears if the light goes out of the screen

It seems that only 3 has been used in Farcry2 and Crysis(only in open area). Other methods are not even used in any game. I might be wrong. :p

Is there any other way to do the volumetric light?

Any suggestion would be appreciated. :)
 
Is there any other way to do the volumetric light?

Any suggestion would be appreciated. :)

lucy_gpu2.jpg


Hi,

I described a method of calculating in-scatter (based on a simplified integral) in Graphics Programming Methods (2003) which sucked because in relied on depth peeling :)

I've developed a new method that uses Shadow Volume Reconstruction (McCool) to create a set of non-overlapping shadow volumes (very important they dont overlap) . The scene is rendered normally and then a final pass is made to render the reconstructed shadow volume and accumulate in-scatter between regions of illumination.

I should write it up but I just don't have to time now days! Benefits are :

no sampling planes
Speed is independent of scene complexity
Can be entirley GPU based.

Fire away if you have any questions.

Rob
 
Last edited by a moderator:
It seems that only 3 has been used in Farcry2 and Crysis(only in open area). Other methods are not even used in any game. I might be wrong. :p

One game I was surprised by using volumetric light, with reasonably good quality and very little perf drop, was Rayman Raving Rabbids (for PC at least). It's hard to get a good screenshot and even harder to know which method they used though.

53149-rrr_01.jpg
 
It looks really nice! Could you please explain more about the details?

Well, volumetric light is caused by the scattering of light due to particles in the air (different particle sizes give different types of scattering). The space around a streetlight appears to glow on a misty night because some light from the lamp is scattered in your direction by water droplets in the air. Light can scatter in and out many times but if you model a single in-scatter it's not too bad.

Some old shader code for 'air lights' - with room for optimisation :)

NB The integral is similar to one that the crytek dev talks about here (page p34)
http://ati.amd.com/developer/gdc/2007/D3DTutorial_Crytek.pdf

Code:
(C) Rob James 2004
// initial set up for inscatter calcs.
// for each fragment the following are constant
// and can be written to a texture
//   dp  1/dp is constant
//   the EyeInscatter is constant
uniform vec3 LightPosition[5];
//varying vec3 ttest ;

void main(void)
{
int i;
float itotal = 0.0;

float mag =dot ( gl_TexCoord[0].xyz,  gl_TexCoord[0].xyz);

   for (i = 0 ; i < 5; i++)
   {
   	//vec3 dt = LightPosition[i] - ttest.xyz;      
   	
   //vec3 dt = LightPosition[i] - gl_TexCoord[0].xyz;
    
    float U =dot( gl_TexCoord[0].xyz, LightPosition[i])/mag;
    
    vec3 Pi =  gl_TexCoord[0].xyz * U;
    
    float rDist = length(Pi - LightPosition[i]);
    
    float ooDp = 1.0/rDist;
    
    float fEye = ooDp * atan(ooDp * length(Pi));
        
    itotal = itotal + fEye*0.05*(-2.5/LightPosition[i].z);
   
    }
    // vec3 coltest = vec3(fEye)*0.05; // cool test!;
     
    gl_FragColor =vec4 (vec3(itotal), 1.0);    
  
}


To look cool the volumetric effect has to account for areas of air that are not illuminated, i.e in shadow. I render the shadow volumes with front faces adding in-scatter and back faces subtracting it, with the level of scatter always being calculated for the WHOLE line between the eye and the surface. So a shadow cast by a simple ball between the viewer and a distant wall will accumulate something like this :

E +++++++++++++++++| <- front face
Y ---------------------------------------------- | <- back face
E ++++++++++++++++++++++++++++++++++++++++++++| wall


which sums to

+++++++++++++++++ ++++++++++++++++++++|

so you get a reduction in in-scatter due to a section of the eye/scene vector being in shadow.

If your eye is in shadows:

E
Y ----------------- | <- back face
E ++++++++++++++++++++++++++++++++++++++++++++++| wall


which sums to

++++++++++++++++++++++++++++++++++++|


Of course if you have no wall then the 'far' point is infinity but that works out OK with just a Max Z in the shader.

Probems occur when shadows overlap (two object overlap from the light pov), hence the need in my method to reconstruct the shadow vols.

I have a demo somewhere if someone would like to host it ?

Rob
 
In one of my early (R300 era) graphics engine demos, I used basically the same algorithm as pocketmoon, but on light volumes only. With light volumes the algorithm is much simpler to get working correctly, as you do not have the same overlapping problem that shadow volumes have. Light volumes look pretty good on interior scenes (sunlight coming in from windows, doors and holes in the walls/ceilings).

The light volumes can be of any shape (do not have to be convex), as long as each light volume is a closed single surface mesh (with no polygon overlapping).
 
I had hoped to find the time to sort out the birds-nest code and write the technique up publication but I have 0 free time :( I think it's a pretty cool, especially being 100% GPU :), and it's nice and 'generic', e.g. you get light volumes, airlights etc for free.

If there's anyone out there who would like to take this on with the hope of writing it up and perhaps porting to DX (it's an OpenGL demo requiring depth buffer reads) then message me and I can dig out the code and project (visual studio).

Rob.
 
Thanks for all your replies!
Sorry for coming back so late :) I was busy of playing with my volumetric light.
pocketmoon66: did you use a 3D texture? How about the performance?
 
Richard: I've noticed the volumetric light effect in "Rayman Raving Rabbids". (Just finished the game, pretty fun :) ) I guess it is the image process based technique. (it seems when the light source goes out of the screen, the light beam disapears.)
 
Thanks for all your replies!
Sorry for coming back so late :) I was busy of playing with my volumetric light.
pocketmoon66: did you use a 3D texture? How about the performance?


No 3d textures (it's all computational) and the demo above runs ~200fps on my 8800GTS. Lucy model is (IIRC) ~65K tris. The HLSL is sub-optimal :)

Performance depends on the size of the depth map/reconstructed shadow volume mesh (200fps is with 512x512). You could go smaller and then blur the in-scatter before adding it to the scene (final pass) for more speed. That still looks cool but you loose some of the fine details.
 
Back
Top