95 lines
3.1 KiB
Plaintext
95 lines
3.1 KiB
Plaintext
//NOTE - The code in this file might seem slightly strange. Intuitivy it would
|
|
//seem better to get Ogre to pass in an array of lights, rather than passing
|
|
//them individually and then building arrays. However, I have had problms with
|
|
//this approach (possibly a bug?)
|
|
|
|
//See http://www.ogre3d.org/phpBB2/viewtopic.php?t=32391
|
|
|
|
struct a2v
|
|
{
|
|
float4 Position : POSITION; //in object space
|
|
float3 Normal : NORMAL;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float4 Position : POSITION; //in projection space
|
|
float4 Color : COLOR;
|
|
float4 TexCoords : TEXCOORD0;
|
|
};
|
|
|
|
struct light
|
|
{
|
|
float4 position;
|
|
float4 diffuseColour;
|
|
float4 attenuation;
|
|
};
|
|
|
|
v2f doWork(a2v IN, float4x4 world, float4x4 viewProj, float textureScale, uniform float4 ambient, int iNoOfLights, light lights[4])
|
|
{
|
|
v2f OUT;
|
|
|
|
OUT.Position = mul(world, IN.Position);
|
|
|
|
OUT.TexCoords.xyz = OUT.Position.xyz /textureScale;
|
|
OUT.TexCoords.w = 1;
|
|
|
|
OUT.Color.rgba = float4(0.0,0.0,0.0,1.0);
|
|
|
|
for(int lightCt = 0; lightCt < iNoOfLights; lightCt++)
|
|
{
|
|
float3 L = normalize(lights[lightCt].position.xyz - OUT.Position.xyz);
|
|
//Calculate attenuation factor.
|
|
float d = distance(lights[lightCt].position.xyz, OUT.Position.xyz);
|
|
float attenuationFactor = 1.0 / (lights[lightCt].attenuation.y + lights[lightCt].attenuation.z * d + lights[lightCt].attenuation.w * d * d);
|
|
// Calculate diffuse component
|
|
float LdotN = max(dot(L, IN.Normal) , 0);
|
|
OUT.Color.rgb += lights[lightCt].diffuseColour.rgb * LdotN * attenuationFactor;
|
|
}
|
|
|
|
OUT.Color.rgb += ambient.rgb;
|
|
|
|
OUT.Position = mul(viewProj, OUT.Position);
|
|
|
|
return OUT;
|
|
}
|
|
|
|
v2f OneLight(a2v IN,uniform float4x4 world, uniform float4x4 viewProj, uniform float textureScale, uniform float4 ambient, uniform light light0)
|
|
{
|
|
light lights[4];
|
|
lights[0] = light0;
|
|
|
|
return doWork(IN, world, viewProj, textureScale, ambient, 1, lights);
|
|
}
|
|
|
|
v2f TwoLights(a2v IN,uniform float4x4 world, uniform float4x4 viewProj, uniform float textureScale, uniform float4 ambient, uniform light light0, uniform light light1)
|
|
{
|
|
light lights[4];
|
|
lights[0] = light0;
|
|
lights[1] = light1;
|
|
|
|
return doWork(IN, world, viewProj, textureScale, ambient, 2, lights);
|
|
}
|
|
|
|
v2f ThreeLights(a2v IN,uniform float4x4 world, uniform float4x4 viewProj, uniform float textureScale, uniform float4 ambient, uniform light light0, uniform light light1, uniform light light2)
|
|
{
|
|
light lights[4];
|
|
lights[0] = light0;
|
|
lights[1] = light1;
|
|
lights[2] = light2;
|
|
|
|
return doWork(IN, world, viewProj, textureScale, ambient, 3, lights);
|
|
}
|
|
|
|
v2f FourLights(a2v IN,uniform float4x4 world, uniform float4x4 viewProj, uniform float textureScale, uniform float4 ambient, uniform light light0, uniform light light1, uniform light light2, uniform light light3)
|
|
{
|
|
light lights[4];
|
|
lights[0] = light0;
|
|
lights[1] = light1;
|
|
lights[2] = light2;
|
|
lights[3] = light3;
|
|
|
|
return doWork(IN, world, viewProj, textureScale, ambient, 4, lights);
|
|
}
|
|
|