I'm working on shadow mapping. Part of the implementation involves drawing 3D models to a depth buffer with recommended 16-bit depth. To that end, I'm first creating a render target as follows:
new RenderTarget2D(graphicsDevice, width, height, false, SurfaceFormat.HalfSingle, DepthFormat.Depth16)
My HLSL shader is shown below.
#define VShaderModel vs_4_0_level_9_1
#define PShaderModel ps_4_0_level_9_1
matrix World;
matrix LightProjection;
struct MapVOutput
{
float4 Position : SV_Position;
float Depth : Depth;
};
MapVOutput MapVShader(in float4 position : SV_Position)
{
MapVOutput output;
output.Position = mul(position, mul(World, LightProjection));
output.Depth = output.Position;
return output;
}
float MapPShader(MapVOutput input) : Depth
{
return input.Depth;
}
technique CreateShadowMap
{
pass Pass0
{
VertexShader = compile VShaderModel MapVShader();
PixelShader = compile PShaderModel MapPShader();
}
};
The idea is to render the scene from the light's perspective (using the LightProjection
matrix) and store depth information only. However, trying to compile this shader gives the following error:
pixel shader must minimally write all four components of SV_Target0
Note that the shader currently uses vs_4_0_level_9_1
and ps_4_0_level_9_1
to compile. I've tried changing those to simply vs_4_0
and ps_4_0
, which lets the shader compile, but causes an error to be thrown during runtime (with a cryptic error message).
Given all this, I have several questions I'm hoping to understand.
- To generate a shadow map, I only need to store 16-bit depth information. Is SurfaceFormat.HalfSingle the correct format to use for this purpose?
- I only need to store 16 bits, but the pixel shader function writes a float (32 bits). How can I write only 16 bits to the render target? If I write a float, is the value properly truncated anyway?
- I've looked at existing shadow map samples and noticed that the
Depth
value inMapVOutput
uses theTEXCOORD0
semantic rather than `DEPTH'. Is DEPTH the correct semantic to use on this variable? - How do I resolve the HLSL error listed above without simply returning a color? Google hasn't given me useful answers so far, and switching compiler versions seems to introduce other problems.
Thank you.