We have some utility functions for reading from the depth buffer. We generate it in an early depth pass, so you can re-use this even on operations that also write to depth.

s&box uses reverse-z depth as of July 2024 - this is the same as Unreal and Godot where 0 is far and 1 is near, this offers much greater precision.

The depth texture is a Depth Mip-chain ( Also known as a Depth Pyramid ), it means the mipmaps of the texture store the minimum/maximum distance of the pixels in two color channels that are up on the chain (2x2, 4x4, 8x8 and so on), we use this to cull things in a GPU-driven manner and to accelerate screen-space traces.

Depth can be separated in 3 spaces, Normalized and Linear depth are the ones you probably care about:

  • Raw: The raw value of the depth buffer
  • Normalized ( Projected Space ): Depth from 0..1 based on the z-near and z-far of the current viewport.
  • Linear ( View Space ): Depth in world units from the camera

API Reference

Depth::Get( float2 ss )

Returns the distance on this screen position.

Depth::Normalize( float d )

Given a distance (like the one returned from Depth::Get), it'll convert it to a float between 0-1 representing the distance between zfar and znear.

Depth::GetNormalized( float2 ss )

Very much like Depth::Get, except the result is already normalized between 0 and 1, where 0 is far away and 1 is near.

Depth::GetWorldPosition( float2 ss )

Return the position in world coordinates of the passed in screenspace position.

Depth::Linearize( float d )

  • Converts a raw value of the depth buffer into one in view space, with world units of distance away from the camera

Depth::GetLinear( float2 ss )

  • Given the position of a pixel, return the position in view space, with world units of distance away from the camera.

Example Usage

On a translucent material, you could calculate the distance between the surface and what's behind the object, for effects like fog:

Material m = ..

float3 fogColor = float3( 0.1f, 0.1f, 0.1f );
float fogRange = 100.0f;

float3 surfacePos = m.WorldPosition;
float3 depthPos   = Depth::GetWorldPosition( m.ScreenPosition );

float dist = distance( surfacePos, depthPos );

m.Emission = lerp( m.Emission, fogColor, saturate( dist / fogRange ) );





Created 26 Nov 2023
Updated 9 Dec 2024