Graphics Reference
In-Depth Information
{
PSOutput output;
float3 lighting = 0;
for ( int i = 0; i < NUMSUBSAMPLES; ++i )
{
float3 normal;
float3 position;
float3 diffuseAlbedo;
float3 specularAlbedo;
float specular-Power;
GetGBufferAttributes( screenPos.xy, i, normal, position,
diffuseAlbedo, specularAlbedo,
specularPower );
lighting += CalcLighting( normal, position, diffuseAlbedo,
specularAlbedo, specularPower );
}
lighting /= NUMSUBSAMPLES;
return float4( lighting, 1.0f );
}
Listing 11.15. Pixel shader code for lighting MSAA subsamples.
One issue we must be aware of with this approach is that it is not always desirable to
sample all subsamples from the g-buffer and compute lighting for them. This is the case
when the geometry rendered for the lighting doesn't fully cover a pixel, or when the depth/
stencil tests don't pass for all subsamples. To ensure that only the appropriate samples are
used, we can take SV_Coverage as an input to the pixel shader. This semantic provides a
uint value, in which each bit corresponds to an MSAA sample. A bit with a value of 1
indicates that the triangle coverage test passed for the corresponding MSAA sample point,
while a value of 0 indicates that it failed. If we perform a bitwise AND of this mask with a
bit value for the current sample in the loop, we can determine whether we should skip the
subsample. The code in Listing 11.16 demonstrates how the code from Listing 11.15 can
be modified to follow this approach.
float4 PSMain( in float4 screenPos : SV_Position,
in uint coverageMask : SV_Coverage ) : SV_Target0
{
PSOutput output;
float3 lighting = 0;
float numSamplesApplied = 0.0f;
for ( int i = 0; i < NUMSUBSAMPLES; ++i )
{
if ( coverageMask & ( 1 << i ) )
Search WWH ::




Custom Search