Well the lighting model doesn't look all that much different from the standard algorithms.
The model I'm using is this:
Code:
float4 PS(float3 Light : TEXCOORD0,float3 Norm : TEXCOORD1,
float3 View : TEXCOORD2,float2 TerrainUV : TEXCOORD3,
float2 DetailUV : TEXCOORD4,float4 Ext : COLOR1) : COLOR
{
//Normalize all vectors -
//First line is same as m_pDevice->SetRenderState(D3DRS_NORMALIZENORMALS,true)
float3 Normal=normalize(Norm);
float3 LightDir=normalize(Light);
float3 ViewDir=normalize(View);
//Diffuse
float Diff=saturate(dot(Normal,LightDir));
//Reflection vector (pure phong)
float3 Reflect=normalize(2*Diff*Normal-LightDir);
//Specular
float Specular=pow(saturate(dot(Reflect,ViewDir)),fGlossiness);
//Base Texel color
float4 TerrainColor=tex2D(Terrain,TerrainUV);
//Detail color
float4 DetailColor=tex2D(Detail,DetailUV);
//Modulate terrain with detail
float4 MixColor=(TerrainColor*DetailColor);
//Constant ambient
float4 Ambient={0.2,0.2,0.2,1.0};
//Final formula for all light in scene
float4 GlobalLight=(Ambient)+ (vDIC * Diff) + (vSpecIC * Specular);
//Final mix
return GlobalLight+MixColor;
}
My formula is just the standard lighting equation. I'm not so sure the formula needs altered any to achieve great lighting effects as it has been tried and tested many thousands of times.
For atmospheric scattering you can check out my thread concerning this very topic. There is a group on www.gamedev.net making an engine called Infinity which looks amazing. They use the shader for scattering as well which is how they are achieving such awesome screenshots.
EDIT:
Materials are just a handy way to stick diffuse color and power, specular color and power (glossiness), emissivity color and power, and ambient color and power into a common structure. And what is Cook? Cook-Torrance?
For example, the Lambertian lighting model makes use of a specular componant for the light itself. This would indicate that the light is emitting a specular color, when in reality, the specular color is the result of the diffuse light color being reflected off the destination surface material. Put more simply, the specular color componant is actually produced through some combination of the surface color and the light color. The diffuse material componant has also been removed. Rather than multiplying the light diffuse by a solid material color, the diffuse light contribution is multiplied by the texture color (assuming the lighting model is being run at the fragment level).
The material and light ambient componants have been left in the equation, to allow for the (cheap) simulation of atmospheric light scattering.
Let me critique here.
For example, the Lambertian lighting model makes use of a specular componant for the light itself. This would indicate that the light is emitting a specular color, when in reality, the specular color is the result of the diffuse light color being reflected off the destination surface material.
There is nothing stated here that is different from the standard lighting equation. Color comes from reflection of a certain wavelength of light. The specular component is simulating what wavelength of light the material reflects at the specular level. It must be different from the diffuse at times because we cannot accurately 'real-time' integrate atmospheric scattering, wavelength changes, etc, at every point along the ray from source to destination and finally to infra-red. The specular component is not a simulation of 'emitting' anything. The specular component is saying that this object reflects this wavelength of specular light. Again we separate them because diffuse alone cannot do specular so we combine the two formulas with differing color values to arrive at the final color.
The diffuse material componant has also been removed. Rather than multiplying the light diffuse by a solid material color, the diffuse light contribution is multiplied by the texture color (assuming the lighting model is being run at the fragment level).
This is no different than the standard model. When textures are involved you have more colors being thrown into the mix. If you add them you get very bright pixels and this is not an accurate simulation of what happens to light. When you modulate them (multiply) this is a very good approximation of what happens to wavelengths of light when they are mixed. If we could just simulate lighting with no textures then modulation would not be needed. However this makes for a boring setup. Textures actually must act as a 'material' that also reflects light. But note that a red texel is going to reflect a diff wavelength of light than a blue texel. Simulating this at the texel level would be ...well....slow. So we account for the entire texture by using modulation, which is not 100% accurate, but it's good enough.
The material and light ambient componants have been left in the equation, to allow for the (cheap) simulation of atmospheric light scattering.
This has nothing to do with simulating atmospheric light scattering and in no way represent what happens. The closest formula that simulates light scattering at constant atmospheric density is the standard fog formula. However, the fog formula fails to take into account the angle of the sun or light source, the emmissive power of the sun, the atmosphere density, the size of the particles in the atmosphere, the wavelength(s) of light those particles reflect, the amount of light that is removed from the atmosphere by rays being reflected off particles back into space, the relative cloud cover which is going to reflect more back into space (out-scattering), the amount of light added by reflection (in-scattering), and optical depth.
Here are facts about light and atmospheric scattering taking from a master's thesis on the subject. Quote taken from Real-Time Rendering of Atmospheric Scattering Effects for Flight Simulators by Ralf Stokholm Nielsen.
- The blue color of the sky is caused by the wavelength dependency of
Rayleigh scattering that favorites the shorter blue wavelength. - When the optical depth approaches infinity, the inscattered color approaches
the color of sunlight. This is why the horizon is white during
the day and red/orange during sunset and sunrise. - Atmospheric scattering is divided into Mie and Rayleigh scattering,
governing the scattering of particles(aerosols) and molecules respectively. - Rayleigh scattering, with equal scattering in the forward and backward
directions, is a subset of the far more complicated Mie scattering. - The Mie scattering phase function can be approximated, using the
Henyey-Greenstein phase function.
The standard fog formula is:
- Lo=original color
- Cfog=fog color
- f(s) - color is a function of distance
- L(s)=Lo*(1-f(s))+Cfog*f(s)
Atmospheric scattering is this:
- L(s,theta) - final color is a function of distance and angle
- Lo=original color
- Fext=coefficient represent extinction of light
- Lin(s,theta) = in-scattering is a function of distance and angle - computed using Rayleigh and Mie scattering as an approximation of the Henyey-Greenstein phase function.
- L(s,theta)=Lo*Fext(s)+Lin(s,theta)
Note the differences. The range fog and even exponential fog formulas fail to account for many real-time atmospheric variables. Also the standard fog formulas attempt to simulate radiant flux, radiosity, and irradiance using pure RGB to RGB values. The actual scattering formula accounts for these and outputs values as radiance values which are then converted to RGB values using wavelength conversion formulas.
Standard lighting formulas for ambient, diffuse, and specular.
X - denotes component-wise multiply --> FinalColor=(A1*A2,R1*R2,G1*G2,B1*B2)
Ambient
C_amb = final ambient color
G_amb = global ambient color
M_amb = material ambient color
C_amb=G_amb X M_amb
Diffuse
C_diff = final diffuse color
N = surface normal
L = light vector
S_diff = diffuse color of light source
M_diff = diffuse color of material
C_diff=(N dot L)S_diff X M_diff
Specular phong
C_spec = final specular color
v = vector to viewer
r = reflected light vector (reflecting light vector about surface normal)
m_gls = glossiness factor
S_spec = specular color of light source
M_spec = specular color of material
C_spec=((v dot r)^m_gls)S_spec X M_spec
Specular Blinn phong
n = surface normal
h = halfway vector
C_spec=((n dot h)^m_gls)S_spec X M_spec
Final equation
C_lit=C_spec+C_diff+C_amb
Expanded
C_lit=i(max(n dot h,0)^m_gls)S_spec X M_spec + max(n dot l,0)S_diff X M_diff) +G+amb X M_amb
Taken from 3D Math Primer for Graphics and Game Development by Fletcher Dunn and Ian Parberry.