vecLightPos[8]
Positions of the 8 most relevant dynamic lights
, including a virtual dynamic light that represents the sun.
The light ranges (lightrange) are stored in the vecLightPos.w component. The light range is zero if a light is not active.
vecLightViewPos[8]
Positions of the 8 most relevant dynamic lights as above, but in view coordinates rather than world coordinates.
vecLightColor[8]
RGB values of the 8 most relevant dynamic lights.
vecLightDir[8]
Normalized direction vectors of the 8 most relevant dynamic lights. If a light is not directional, i.e. if it is not the sun and its SPOTLIGHT flag is not set, all components of this vector are 0.
Otherwise the w component is set to the range of the light.
Type
float4
Remarks
- A7.20 The array is sorted from close to far lights, with vecLightPos[0] being the position of the closest light.
The sun has the largest distance and is thus the last light in the array.
- A7.60
In postprocessing shaders, the light values are set to the 8 closest lights that overlap the frustum of the postprocessing view. If the postprocessing view has a genius, the light values are set to the closest lights in range of the genius entity instead.
- 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 lights with a nonzero range for light calculation. The .w component contains the range, therefore use only the
vecLightPos.xyz components for matrix multiplications.
-
The light range of the sun can be adjusted through the third component (roll) of the sun_angle vector (default: 100,000).
If sun_light is zero, the sun is not included in the array. This can be used for indoor levels when you don't want sun light to affect shaders.
-
The type of light can be determined in shaders in the following way: vecLightDir[i].w > 10000 => sun; vecLightDir[i].w > 0 => spotlight or directional light; otherwise, pointlight.
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
► latest
version online