A texture may be a shadow map projected from a light source. In our paper [X3D Shadow Maps] we have noted that the shadow should scale only the appropriate light source contribution. This allows to observe correct shadows from multiple light sources. This means that shadow map textures must be used in a different stage of the calculation than normal textures.
Our plugs idea allows to do this, in a clean and concise way.
At the place where TextureShader
is created in the pseudo-code
from the previous section, we treat shadow maps specially.
If the light source corresponding to the shadow map affects our shape
then we do not apply the texture in a usual way. Instead, we call
the Plug
function to augment the specific light source shader
with a shadow check, like this:
if Texture is GeneratedShadowMap and Texture.light affects the shape then Plug(fragment, 'uniform sampler2DShadow shadowMap01; void PLUG_light_scale(inout float scale, ...) { scale *= shadow2DProj(shadowMap01, shadowMap01TexCoord).r; }', LightShader);
The simple call to shadow2DProj
may be replaced with a variant
of the Percentage Closer Filtering
(see [GPU Gems PCF]).
The calculation of light effects has to be complicated a little
to make it work.
In our simple pseudo-code, we added the effects to the LightShader
and then we immediately merged LightShader
with the
FinalShader
. Now, we need to remember the
LightShader
value for a longer time,
in case it should be augmented with a shadow map.
Alternatively, we could search
for corresponding shadow maps at the moment
when LightShader
is created.