Reconstruct Position from Depth - Advanced Rendering - Shader Learning

Advanced Rendering

Reconstruct Position from Depth

Task

Reconstruct the fragment's world position from its depth value in iDepthBuffer.

Theory

Reconstructing the fragment's world position from its depth value involves a series of transformations that convert depth values back to world space coordinates.


This approach is particularly advantageous in deferred rendering, where multiple render targets (MRT) are used to store various attributes of the scene, such as color, normals, and depth. By reconstructing the world position from the depth value, we can eliminate the need for a separate position texture. This not only simplifies the rendering pipeline but also significantly reduces memory usage, as storing high-resolution position data for every fragment can be quite memory-intensive.


Steps to Restore World Position


1. Obtain Depth Value. The depth value of a fragment is stored in a depth texture, representing the distance from the camera to the fragment in the range [0, 1]:

float depth = texture(iDepthBuffer, uv).r;

2. Reconstruct NDC. Use the depth value and the fragment's screen coordinates to reconstruct the normalized device coordinates:

vec3 ndc = vec3(uv, depth) * 2.0 - 1.0;

3. Transform to View Space. Transform the NDC to view space using the inverse of the projection matrix.

vec4 viewPos = inverseProjectionMatrix * vec4(ndc, 1.0); 
viewPos /= viewPos.w;

By multiplying the NDC coordinates by the inverse projection matrix, we get the view space position in homogeneous coordinates. To convert from homogeneous coordinates back to 3D coordinates, we divide by the w component.


4. Transform to World Space. Transform the view space position to world space using the inverse of the view matrix.