Graphics Reference
In-Depth Information
The next step is to calculate the view ray vector during our lighting pass. We'll do this
by first determining the vector from the camera to the vertex position in the vertex shader.
Then in the pixel shader, we'll normalize this vector to get the final view ray vector. This
vector is then multiplied with the distance value sampled from the g-buffer and added to
the camera position to reconstruct the original surface position. Note that the vertex posi-
tion, camera position, and resulting camera ray can be in any coordinate space, as long as
the same space is used for all three of them. This allows reconstructing either a view space
or a world space position. The code in Listing 11.10 uses world space for simplicity of
presentation.
// -- Light vertex shader --
#if, VOLUMES
II Calculate the world space position for a light volume
float3 positionWS = mul(input.PositionOS, WorldMatrix);
#elif QUADS
// Calculate the world space position for a full-screen quad (assume input
// vertex coordinates are in [-1,1] post-projection space)
float3 positionWS = mul ( input.PositionOS, InvViewProjMatrix);
#endif
// Calculate the view ray
output. ViewRay = positionWS - CameraPositionWS;
// -- Light Pixel shader --
// Normalize the view ray, and apply the distance to reconstruct position
float3 viewRay = normalize(input. ViewRay);
float viewDistance = DistanceTexture.Sample(PointSampler, texCoord);
float3 positionWS = CameraPositionWS + viewRay * viewDistance;
Listing 11.10. Light shader code for view ray calculation and position reconstruction.
This provides us with a flexible and fairly efficient method for reconstructing position
from only a single high-precision value stored in the g-buffer. However, we can still make
further optimizations if we restrict ourselves to view space, since in view space the view
frustum is aligned with the Z-axis.
When reconstructing a view space position, we can extrapolate the view ray until it
intersects with the far clipping plane. Computing this intersection point is trivial, since it's
the point where the Z component is equal to the far clip distance. When rasterizing a quad
for a directional light, it's even simpler, since the frustum corner position can be linearly
interpolated. With the Z component of the view ray set to a known value, it is no longer
necessary to normalize the view ray vector in the pixel shader. Instead, we can multiply it
by a value that scales along the camera's z-axis to get the final reconstructed position. In the
case where Z is the far clip distance, we want to scale by a ratio of the original surface depth
relative to the far clip plane. In other words, the surface's view space Z divided by the far
Search WWH ::




Custom Search