For several years now I've been planning on trying out spherical harmonic irradiance lighting.
So today I threw together a quick little version. It has 2 main abilities:
- (static) It generates ambient lighting of ogre models using 100 (or more) random samples from the current skybox cubic texture as fake lights added to the spherical harmonic.
- (dynamic) Every frame it can take the list of all lights affecting a model, compress them into a spherical harmonic and pass to the shader. Lights can be moving or changing colour.
The hardest part overall was getting the cubic texture of the skybox sampled. I'll probably find a built in function to do it any minute now.
Nothing particularly new (I've seen at least one sh based model pic on here before, from Hexidave 2 years ago), I just felt like posting something. I actually was about to start this the other day, but I discovered a problem (post about it soon) which made me thing about vertex optimisation instead.
I'll probably wiki the skybox code when I get it a bit more stable (it only handles one pixel format right now, and does a lock/unlock per pixel).
A little experiment in lighting
- Kojack
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 534
- Wretched_Wyx
- Orc
- Posts: 498
- Joined: Thu Mar 16, 2006 5:27 pm
- Contact:
Re: A little experiment in lighting
Awesome job. Lighting is one of my favorite rendering topics and SH among my favorite techniques. What shader language did you use, Cg?
- Kojack
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 534
Re: A little experiment in lighting
hlsl, but cg should be easy. Here's the shader:
I should probably use some matrices or something to pass in the sh to the shader, but the above works for now.
Just pure ambient to test the effect.
Code: Select all
void sh_vp(float4 position : POSITION,
float3 norm : NORMAL,
out float4 oPosition : POSITION,
out float4 colour : COLOR,
uniform float4x4 worldViewProj,
uniform float3 shval0,
uniform float3 shval1,
uniform float3 shval2,
uniform float3 shval3,
uniform float3 shval4,
uniform float3 shval5,
uniform float3 shval6,
uniform float3 shval7,
uniform float3 shval8)
{
oPosition = mul(worldViewProj, position);
colour.a = 1;
colour.xyz = shval0;
colour.xyz += shval1 * norm.x;
colour.xyz += shval2 * norm.y;
colour.xyz += shval3 * norm.z;
colour.xyz += shval4 * (norm.x * norm.z);
colour.xyz += shval5 * (norm.z * norm.y);
colour.xyz += shval6 * (norm.y * norm.x);
colour.xyz += shval7 * (3.0f * norm.z * norm.z - 1.0f);
colour.xyz += shval8 * (norm.x * norm.x - norm.y * norm.y);
}
Just pure ambient to test the effect.
- calsmurf2904
- Orc
- Posts: 401
- Joined: Tue Sep 16, 2008 9:39 pm
- Location: Netherlands
Re: A little experiment in lighting
You haven't been standing still lately...with all your "experiments" xD
Looks great....what's the FPS?
Looks great....what's the FPS?
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
- Kojack
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 534
Re: A little experiment in lighting
Static lighting, 200 fake lights sampled from the environment into the SH as a preprocess step, using the ogre head, running at 1024x768 on my 7800gtx: 1740+fps (the model was spinning, fps varies slightly)
So it's pretty fast.
Dynamic lighting:
25 randomly placed and coloured point lights around the ogre head.
Left pic: standard ogre material. 530fps
Right pic: Regular lighting not used. Every update (60hz rate) a new SH is built using the list of every light near the ogre head (all 25 in this case) and passed to the shader (same shader as the static light one I posted above, only the c++ code is different between static and dynamic). 1783fps.
So I can use 25 lights in real time at pretty high frame rates.
The best use for this stuff is something like this:
- Get all lights near an object.
- The most important (based on brightness and distance, the ones which would affect the model the most) 3 lights are treated as normal lights.
- Every other light within range after the most important 3 is compressed into the spherical harmonic.
- The shader uses 3 lights for all the usual per pixel diffuse/specular/normal mapping/etc calculations. The ambient term in the shader is actually extracted per vertex (or pixel, but vertex is fine since it's low frequency anyway) from the SH using the vertex's normal.
Of course the numbers can vary (1 real light instead of 3, etc). But it gives you all the typical lighting equation as normal, it just replaces the ambient so every light gets to have some effect without doing all the intensive math of light-per-pass techniques.
To get some global illumination without chucking tone of ogre lights into the scene, you could get your modeller to generate SH's at various locations in the world and export them, then in ogre you find the nearest one to each model and interpolate between them. So you have pregenerated SH's for indoors, outside, etc.
So it's pretty fast.
Dynamic lighting:
25 randomly placed and coloured point lights around the ogre head.
Left pic: standard ogre material. 530fps
Right pic: Regular lighting not used. Every update (60hz rate) a new SH is built using the list of every light near the ogre head (all 25 in this case) and passed to the shader (same shader as the static light one I posted above, only the c++ code is different between static and dynamic). 1783fps.
So I can use 25 lights in real time at pretty high frame rates.
The best use for this stuff is something like this:
- Get all lights near an object.
- The most important (based on brightness and distance, the ones which would affect the model the most) 3 lights are treated as normal lights.
- Every other light within range after the most important 3 is compressed into the spherical harmonic.
- The shader uses 3 lights for all the usual per pixel diffuse/specular/normal mapping/etc calculations. The ambient term in the shader is actually extracted per vertex (or pixel, but vertex is fine since it's low frequency anyway) from the SH using the vertex's normal.
Of course the numbers can vary (1 real light instead of 3, etc). But it gives you all the typical lighting equation as normal, it just replaces the ambient so every light gets to have some effect without doing all the intensive math of light-per-pass techniques.
To get some global illumination without chucking tone of ogre lights into the scene, you could get your modeller to generate SH's at various locations in the world and export them, then in ogre you find the nearest one to each model and interpolate between them. So you have pregenerated SH's for indoors, outside, etc.
- calsmurf2904
- Orc
- Posts: 401
- Joined: Tue Sep 16, 2008 9:39 pm
- Location: Netherlands
Re: A little experiment in lighting
so only thing this is doing is making the skybox as a light ?
That's awesome....would be cool if you can do this with something like caelum
That's awesome....would be cool if you can do this with something like caelum
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
- Kojack
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 534
Re: A little experiment in lighting
The static one is turning the skybox into a light.so only thing this is doing is making the skybox as a light ?
The dynamic one is turning all point lights into a single ambient light.
Of course you could combine them and have the dynamic lights merged in to the same SH as the skybox, I just had them separate to test the effect.
- Wretched_Wyx
- Orc
- Posts: 498
- Joined: Thu Mar 16, 2006 5:27 pm
- Contact:
Re: A little experiment in lighting
I would think it wouldn't be to hard to take the Caleum directional light and use that a "normal" light. Then take the atmospheric ambient lighting from Caleum, and add that in the ambient term. Erm, all this in the shader I mean. So the SH and Caleum ambiance could be the ambient term.
- xadhoom
- Minaton
- Posts: 973
- Joined: Fri Dec 28, 2007 4:35 pm
- Location: Germany
- x 1
Re: A little experiment in lighting
@Kojack: Are you still working on this implementation? I would be interested if your solution could be adapted to work with caelums dynamic lighting system.
xad
xad