Sign in to follow this  
zhugel_007

volumetric light

Recommended Posts

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. :)

Share this post


Link to post
Share on other sites
Well there are two ways to do this.

Assume you have points where the ray enters & exits the light volume.

If you use procedural light falloff, you can take path integral of the falloff function across the given segment. This is the way UE3 does it, for details see Gears of War shaders, eg. function SphereLineIntegral().

Or you can take a fixed/adaptive number of samples of falloff and projective texture along this segment, which of course will result in some artifacts.

Personally I prefer using procedural falloff and discrete sampling of projective texture combination.

Share this post


Link to post
Share on other sites
Quote:
Original post by zhugel_007
Is there any other way to do the volumetric light?
Any suggestion would be appreciated. :)

Yes,it is.There are a lot of other methods,for example volumetric light demo on my page,in part "2005-2006 Demos"
(I aviod to place direct link,because one of dounload steeps- via russian language page)

Share this post


Link to post
Share on other sites
Quote:
Original post by Krokhin
Quote:
Original post by zhugel_007
Is there any other way to do the volumetric light?
Any suggestion would be appreciated. :)

Yes,it is.There are a lot of other methods,for example volumetric light demo on my page,in part "2005-2006 Demos"
(I aviod to place direct link,because one of dounload steeps- via russian language page)


Wow, that looks great! Any details?

Share this post


Link to post
Share on other sites
Quote:
Original post by KRIGSSVIN
If you use procedural light falloff, you can take path integral of the falloff function across the given segment. This is the way UE3 does it, for details see Gears of War shaders, eg. function SphereLineIntegral().

Or you can take a fixed/adaptive number of samples of falloff and projective texture along this segment, which of course will result in some artifacts.

Personally I prefer using procedural falloff and discrete sampling of projective texture combination.

Do you have any link/paper/something about those techniques?

Share this post


Link to post
Share on other sites
Quote:
Original post by agi_shi
Any details?

Breafly-I use in this method per one omni (point) light:
- one cubemap with 8-bit range in alpha for all non-transparent
objects around light (closer than point light max.range)
- additional cubemap,having also 8-bit range in alpha and transperensy color in RGB,
for all transparent objects objects around light (closer than point light max.range).This ranges in both cumebaps normalised to max.light range(=radius)
-rendering in separate RT,having ~1/4 of backbuffer size for all lights ~100 spheres around each.
For each sphere I make comparison sphere radius and range in cubemaps,i.e. calculations just like in case of cube shadowmaps using.
-last steep -bluring and applying this RT like a full-screen quad after scene rendering.
Cubemaps need refresh in case of light or scene object(s) positions change,
their sise~128x128.Number of spheres per light depends from angular size of light
radius in camera space( in this demo min=16,max=128),it's the main trick for increasing speed.

ps. I don't remember .exe file version in this demo pack,but you can try
change volume light quality.
In 4th string in scene.ase file (*SCENE_FILENAME "volumelight.max" +VLH)
+VLH could be replaced to +VLL / +VLM or +VLU
Also could work( may be) such keys in this string,in addition:
+AEL / +AEM /+AEH -auto exposhure
+DFL /+DFM / +DFH -depth of field...

[Edited by - Krokhin on December 21, 2008 3:02:17 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by zhugel_007
Could you please explain more about the use of the cubemap?
I am still confused of how you use the cubemap.

Hi,unfortunately now I'm faraway from my computer.
I will look at source code ,try to recall something and answer you
only after 1/6/2009,ok?

Share this post


Link to post
Share on other sites
I'm sorry for delay:)
Firstly I must say that I use DX9 API+D3DX library
The simplest explanation,for non-transparent shapes is:
1.Create cube texture as render target,and 2D-texture 1/8-1/4 screen size
as render target (once on initialisation)
2.Set camera in the center of light and render in faces of cube texture
background with constant alpha=1,and all shapes which is near then
point light rarius.When rendering shape,in vertex shader calculate range
from camera to vertex,divide by light radius ,saturate to [0..1]
range and pass as color to pixel shader.In pixel shader simply return this value (pass directly to output).You will have a cube texture with 8-bit range encoded in alpha.
Refresh /rendering of cubemap can be done on demand,not every frame.
3.Render concentric spheres ( ~16x16 strips) around light to 2D-texture rendertarget :
-pass vertex normal from vertex shader to pixel shader
-in vertex shader calculate range from camera to vertex,divide by light radius ,saturate to [0..1] range and pass as color to pixel shader(i.e. the same operation as cubemap rendering)
In pixel shader use normal as texture coordinate for cubemap sampling,
and compare alpha of this sample and passed color.
If color>alpha - color for sphere fragment=0,light source is covered for this point.
else color for sphere fragment=1,light passes to this point.
Alpha blend must be set to "ADD" while rendering all spheres.
Color for sphere fragment must be multiplyed to attenuation-linear for example.
Main trick here to avoid "steeps" very simple:displays still have 256 gradations.If you will render 256 spheres with linear attenuation from
256 to zero (actually 1.0->0.0),you will get a smooth picture anyway:)
No need to set initial attenuation=1.0,of couse-litted dust or smoke usually
has less intensity.You can try initially 0.128,it will be quite enough,and you must draw 32 sphere in this case.
You can smooth this RT additionally,using ping-pong method.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this