
The information in MPassContext provides sufficient information to indicate when a plug-in is being invoked for rendering certain passes required to support SSAO (screen-space ambient occlusion).
The internal algorithm for SSAO requires a specific normal-depth pass to produce intermediate results. By default, the renderer sets up a specific shader to be used in this pass. In the case where a plug-in shader causes geometry to be displaced or normal to be modified, it is possible to override this default shader.
This normal-depth pass can be detected by querying MPassContext information in a similar fashion to how shadow map passes can be detected (see Section 4.2.1 Shadowing control). For this pass, the pass identifier is: MPassContext::kNormalDepthPassSemantic.
If any tessellation shaders are required, then the override should be added to an MPxShaderOverride instead of an MShaderInstance.
To add support, any custom shader should take into account the following conditions.The following is a sample of the shader used for this pass, written in HLSL:
// Vertex shader input structure.
struct VS_INPUT_NormalDepth
{
float3 Pos : POSITION;
float3 Normal: NORMAL;
};
// Vertex shader output structure.
struct VS_TO_PS_NormalDepth
{
float4 HPos : SV_Position;
float4 NormalDepth : TEXCOORD0;
};
// Vertex shader.
VS_TO_PS_NormalDepth VS_NormalDepth(VS_INPUT_NormalDepth In)
{
VS_TO_PS_NormalDepth Out;
// Transform the vertex from object space to clip space.
Out.HPos = mul(float4(In.Pos, 1.0f), gWVPXf);
// Record the normal and depth components for the pixel shader.
Out.NormalDepth.xyz = mul(In.Normal, gWVITXf);
Out.NormalDepth.w = mul(float4(In.Pos, 1.0f), gWVXf).z;
return Out;
}
// Pixel shader output structure.
struct PS_OUT
{
float4 Normal : SV_Target0;
float4 Depth : SV_Target1;
};
// Pixel shader.
PS_OUT PS_NormalDepth(VS_TO_PS_NormalDepth In)
{
PS_OUT Out;
// Set the normal for an unsigned normalized integer target, and depth for a floating-point
// target.
Out.Normal = float4((normalize(In.NormalDepth.xyz) + 1.0f) * 0.5f, 0.0f);
Out.Depth = In.NormalDepth.wwww;
return Out;
}