Graphics Reference
In-Depth Information
// For a directional lightj the vertices were already on the far clip plane so
// we don't need to extrapolate
float3 viewRay = input.PositionVS.xyz;
#endif
// Sample the depth and scale the view ray to reconstruct view space position
float normalizedDepth = DepthTexture.Sample(PointSampler, texCoord).xj
float3 positionVS = viewRay * normalizedDepth;
Listing 11.11. Shader code for optimized view space position reconstruction.
Avoiding normalization of the view ray in the pixel shader reduces the number of
math operations, particularly in the directional light case where the view ray is already
extrapolated. Another point to be aware of is that the depth value stored in the g-buffer is
always ofjthe range [0, 1]. This means you can store it in a normalized integer format (such
as DXGI_F0RMAT_R16_UNORM) without having to do any rescaling after sampling it in the
pixel shader.
While the above techniques work well when a depth or distance value is explicitly
written to the g-buffer, it is also possible to avoid storing a value altogether. This can be
done by sampling the depth stencil buffer used when rendering the g-buffer pass. A depth
buffer will store the post-projection Z value divided by the post-projection W value, where
W is equal to the view-space Z component of the surface position. This makes the value
initially unsuitable for our needs, but fortunately it's possible to recover the view-space Z
component using the parameters of the perspective projection(Baker). Once we do that, we
can convert it to a normalized depth value and proceed with the same approach outlined
above. However, this is unnecessary. Instead of extrapolating the view ray to the far clip
plane, if we instead clamp it to the plane at Z = 1 we can scale it by the view-space Z with-
out having to manipulate it first. Essentially, we scale the view ray in the vertex shader,
rather than scaling the Z value in the pixel shader, which saves us an extra pixel shader
math operation.
// Light vertex shader
#if VOLUMES
// Calculate the view space vertex position
output.PositionVS = mul(input.PositionOS, WorldMatrix);
#elif QUADS
// For a directional light we can clamp in the vertex shades since we
// only interpolate in the XY direction
float3 positionVS = mul(input.PositionOS, InvProjMatrix) ;
output.ViewRay = float3(positionVS.xy / positionVS. z, 1.0f);
#endif
Search WWH ::




Custom Search