Table of Contents

Class CPUDepthSampler

A utility for asynchronously sampling world-space positions from normalized device coordinates (NDC) in the depth texture using a compute shader. This class batches requests for efficiency and ensures main-thread safety for XR frame access.

public class CPUDepthSampler : DontCreateNewSingleton<CPUDepthSampler>
Inheritance
object
CPUDepthSampler

Remarks

This sampler relies on DepthPreprocessor for depth texture and reprojection data. It is designed for CPU-side depth queries, such as raycasting against environment depth or occlusion checks in custom XR interactions.

Usage Notes:

  • Requests are batched and dispatched at the end of the frame via Uralstech.UXR.QuestMeshing.CPUDepthSampler.DispatchForSamplingAsync() to minimize GPU overhead.
  • All public sampling methods require main-thread execution for XR subsystem access and yield to the main thread if called from elsewhere.
  • Invalid NDC positions (outside [0,1]) will return invalid results—validate with IsValidNDC(Vector2) before sampling.
  • Errors (e.g., GPU readback failures) return null; check return values before use.
Single Sample:
if (CPUDepthSampler.Instance.ConvertToNDCPosition(worldPos, DepthEye.Left, out Vector2? ndc)
    && CPUDepthSampler.IsValidNDC(ndc.Value))
{
    Vector3? depthPos = await CPUDepthSampler.Instance.SampleDepthAsync(ndc.Value);
    if (depthPos.HasValue) { /* Process data */ }
}
Batch Sample:
ArraySegment<Vector3>? results = await sampler.BatchSampleDepthAsync(new Vector2[] { ndc1, ndc2 });
if (results.HasValue)
{
    foreach (Vector3 pos in results.Value) { /* Process data */ }
}

Methods

Awake()

protected override void Awake()

BatchSampleDepthAsync(IEnumerable<Vector2>)

Asynchronously samples world-space positions for a batch of NDC coordinates in the depth texture.

public Awaitable<ArraySegment<Vector3>?> BatchSampleDepthAsync(IEnumerable<Vector2> ndcPositions)

Parameters

ndcPositions IEnumerable<Vector2>

The enumerable of NDC positions (x,y in [0,1] range) to sample.

Returns

Awaitable<ArraySegment<Vector3>?>

An ArraySegment of results in input order, or null if data is unavailable or sampling fails.

Remarks

This queues the batch and dispatches at end-of-frame for efficiency. Ideal for multiple queries (e.g., raycast hits). The returned segment shares the underlying results array (do not modify it externally).

ConvertToNDCPosition(Vector3, DepthEye, out Vector2?)

Converts a world-space position to normalized device coordinates (NDC) in the depth texture for the specified eye.

public bool ConvertToNDCPosition(Vector3 worldPosition, DepthEye eye, out Vector2? ndcPosition)

Parameters

worldPosition Vector3

The world-space position to project.

eye DepthEye

The eye for which to compute the NDC (affects reprojection matrix).

ndcPosition Vector2?

The resulting NDC position (x,y in [0,1] range), or null if preprocessor data is unavailable.

Returns

bool

true if conversion succeeded (preprocessor data available); otherwise false.

Remarks

This uses the current frame's reprojection matrix from DepthReprojectionMatrices.

IsValidNDC(Vector2)

Determines if an NDC position is valid for depth texture sampling.

public static bool IsValidNDC(Vector2 position)

Parameters

position Vector2

The NDC position to validate.

Returns

bool

true if the position is within the [0,1] range for both x and y; otherwise false.

SampleDepthAsync(Vector2)

Asynchronously samples the world-space position at the given NDC coordinates in the depth texture.

public Awaitable<Vector3?> SampleDepthAsync(Vector2 ndcPosition)

Parameters

ndcPosition Vector2

The NDC position (x,y in [0,1] range) to sample.

Returns

Awaitable<Vector3?>

The world-space Vector3 at the sample point, or null if data is unavailable or sampling fails.

Remarks

This queues the request and batches it with others for end-of-frame dispatch.

Start()

protected void Start()