Graphics Reference
In-Depth Information
{
float3 normal;
float3 position;
float3 diffuseAlbedo;
float3 specularAlbedo;
float specularPower;
GetGBufferAttributes( screenPos.xy, i, normal,
position, diffuseAlbedo,
specularAlbedo, specularPower );
lighting += CalcLighting( normal, position,
diffuseAlbedo, specularAlbedo,
specularPower );
++numSamplesApplied;
}
}
lighting /= numSamplesApplied;
return float4( lighting, l.0f );
}
Listing 11.16. Pixel shader code for lighting MSAA subsamples with coverage test.
Another way to ensure proper g-buffer sampling is to run the pixel shader at per-
sample frequency instead of at per-pixel frequency. In this case, the pixel shader only runs
if the triangle coverage test and the depth/stencil test both passed for a given sample, so
there is no need to check the input coverage mask.
Using MSAA gives us better performance than supersampling, because we don't
have to render the g-buffer at a higher resolution. However, we can do even better. When
rendering with MSAA, the majority of the pixels on the screen will be fully covered by
a triangle from the scene geometry. Consequently, all of the subsamples of a given pixel
within the g-buffer will be the same. We can take advantage of this to optimize the ap-
proach outlined above by only lighting one subsample for pixels where all subsamples are
identical. One possible approach is to read all subsamples of one of the g-buffer textures
in the lighting pass, compare for equivalence, and then dynamically branch based on that
result. While this can work in some cases, it's possible that the subsamples will be identi-
cal (or within the threshold used) for one g-buffer texture, while one or more of the other
textures are different. In addition, performance will vary depending on the granularity of
dynamic branching in the GPU. If one pixel takes the slow branch, where it evaluates all
subsamples, this can cause all adjacent pixels within a certain tile size to take both sides
of the branch.
To avoid this issue, a stencil mask can be used, rather than branching in the pixel
shader. The mask can be generated with a full-screen pass that samples the g-buffer and
Search WWH ::




Custom Search