vecLightPos[8]
vecLightColor[8]
World positions and rgb values of the 8
closest active dynamic
lights, A7 including the sun.
Their
ranges
(entity.lightrange) are stored in
the vecLightPos.w component.
The
light range is zero if a light is not active.
Type
vector, read-only
Remarks
- In an average vs 1.1 shader, the maximum number of instructions is only
sufficient for calculating about 6 dynamic lights. Higher shader versions
can theoretically support 30
or more simultaneous dynamic lights.
- Use only active lights with a nonzero range for light calculation.
A7 Dynamic
lights are sorted to the begin of the array and the sun position is placed
behind the last dynamic light.
- Because the vecLightPos.w component contains the range, use only the
vecLightPos.xyz components for matrix multiplications.
Example
// Use dynamic lights in a vertex shader
float4 vecLightPos[8];
float4 vecLightColor[8];
...
// return the dynamic light on the surface
float4 DoPointLight(float3 P, float3 N, int i)
{
// calculate the light ray pointing from the light to the surface
float3 D = (float3)vecLightPos[i]-P;
// calculate the angle between surface and light ray
float NdotL = dot(N,normalize(D));
// modulate the light by the surface angle
float4 Color = vecLightColor[i] * NdotL;
// calculate the light attenuation factor
float fac = 0.f;
if (NdotL >= 0.f && vecLightPos[i].w > 0.f)
{
// get the distance factor
float LD = length(D)/vecLightPos[i].w;
if (LD < 1.f)
fac = 1.f - LD;
}
return Color * fac;
}
VS_OUT TerrainLight_VS (
float4 inPos : POSITION,
float3 inNormal : NORMAL)
{
VS_OUT Out;
// transform the vector position to screen coordinates
Out.Pos = mul(inPos,matWorldViewProj);
// Terrains don't need to rotate the normal, but it must be normalized
float3 N = normalize(inNormal);
float3 P = mul(inPos,matWorld);
// Add 6 dynamic lights (maximum for vs 1.1)
Out.Color = float4(0.f,0.f,0.f,0.f);
for (int i=0; i<6; i++)
Out.Color += DoPointLight(P,N,i);
...
return Out;
}
See also:
material, shaders,
predefined shader variables