I'm using DirectX 11 and shader model 5.
There are many tutorials online for writing engines and shaders for shadow mapping. I have found an issue which seems to have a hard to find answer.
Typical shadow maps can be created by setting null render targets, assigning a depth/stencil, and setting a null pixel shader. What about the case where I want to sample a texture to determine an objects transparency and discard the pixel based on that transparency (i.e. shadow mapping a tree or chainlink fence)? In this case I need a pixel shader which samples a texture and outputs an alpha value to determine whether to write a pixel to the depth stencil. How do I output an alpha value if there are no render targets?
The regular pixel shader for an object might be:
struct OutputStruct
{
float4 Diffuse : SV_Target0;
float4 WorldPos : SV_Target1;
float4 Normal : SV_Target2;
}
OutputStruct PS(InputStruct Input)
{
OutputStruct output = (OutputStruct)0;
// perform pixel shading operations
return output;
}
This seems to be what I want:
struct OutputStruct
{
}
OutputStruct PS(InputStruct Input)
{
OutputStruct output = (OutputStruct)0;
// perform pixel shading operations
return output;
}
Where do I determine whether to write to the depth stencil based on the pixel shader operations? How do I output an alpha (0 or 1 in value)? Remember that the blend state is defined for each render target slot of which I have none.
clip (-1)
directly from the pixel shader that writes depth for any alpha sample that fails; no color output necessary. You will make the shadow map generation perform slightly worse by doing this (it violates certain hardware optimizations to arbitrarily discard a pixel during the evaluation of a pixel shader), but it might not be all that bad considering how simple the pixel shader is. \$\endgroup\$discard()
orclip(-1)
? \$\endgroup\$discard
(GLSL) orclip(-1)
(HLSL). It tells the fragment/pixel shader to throw away the results for the current pixel; this includes color, depth, stencil. It is as though the pixel never existed. In fact, in modern OpenGL there is no fixed-function alpha test anymore, you actually have to implement alpha testing yourself usingdiscard
. \$\endgroup\$