Skip to content

feat: add reverse-z depth buffer support for WebGPU#8703

Open
MAG-AdrianMeredith wants to merge 3 commits into
playcanvas:mainfrom
MAG-AdrianMeredith:reverse-z-webgpu
Open

feat: add reverse-z depth buffer support for WebGPU#8703
MAG-AdrianMeredith wants to merge 3 commits into
playcanvas:mainfrom
MAG-AdrianMeredith:reverse-z-webgpu

Conversation

@MAG-AdrianMeredith
Copy link
Copy Markdown
Contributor

@MAG-AdrianMeredith MAG-AdrianMeredith commented May 8, 2026

Description

Add support for far view distances via reverse z in webgpu

  • Opt-in via "reverseZ" flag on createGraphicsDevice options. WebGPU only.
const gfxOptions = {
    deviceTypes: ['webgpu'],
    // opt in to reverse-z when running on WebGPU; ignored on WebGL2
    reverseZ: true
};

const device = await pc.createGraphicsDevice(canvas, gfxOptions);
const createOptions = new pc.AppOptions();
createOptions.graphicsDevice = device;
const app = new pc.AppBase(canvas);
app.init(createOptions);
  • Translates compare funcs, depth bias, depth clear, viewport-z remap.
  • Adds graphics/reverse-z example demonstrating precision at far distances.

Before (WebGL2)
image

After (WebGPU with reverseZ flag)
image

Checklist

  • I have read the contributing guidelines
  • [x My code follows the project's coding standards
  • This PR focuses on a single change

- Opt-in via  flag on createGraphicsDevice options. WebGPU only.
- Translates compare funcs, depth bias, depth clear, viewport-z remap.
- Adds graphics/reverse-z example demonstrating precision at far distances.
@Maksims
Copy link
Copy Markdown
Collaborator

Maksims commented May 8, 2026

Nice.
Please write added API into the first post, it makes it easier to understand how to access a new feature.

@willeastcott willeastcott added enhancement Request for a new feature area: graphics Graphics related issue labels May 8, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds opt-in reverse‑Z depth buffering for the WebGPU backend to improve depth precision at very large view distances, with corresponding shader/runtime adjustments and an example showcasing reduced z-fighting.

Changes:

  • Introduces reverseZ device creation option (WebGPU-only) and exposes GraphicsDevice.isReverseZ.
  • Updates WebGPU depth compare, depth bias sign, depth clears, and camera projection transform to support reverse‑Z.
  • Updates GLSL/WGSL shader chunks (skybox, particles, fog/depth utilities, picking, shadows) to correctly interpret reversed hardware depth; adds a reverse‑Z example and a small unit test for the flag.

Reviewed changes

Copilot reviewed 40 out of 42 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/platform/graphics/graphics-device.test.mjs Adds unit coverage for the isReverseZ flag defaulting/option behavior.
src/scene/shader-lib/wgsl/chunks/skybox/vert/skybox.js Adjusts skybox depth placement for reverse‑Z.
src/scene/shader-lib/wgsl/chunks/particle/vert/particle_end.js Fixes screenspace particle clip-space Z for reverse‑Z.
src/scene/shader-lib/wgsl/chunks/particle/vert/particle_cpu_end.js Fixes screenspace CPU particle clip-space Z for reverse‑Z.
src/scene/shader-lib/wgsl/chunks/lit/frag/pass-shadow/litShadowMain.js Flips explicitly written shadow depth when reverse‑Z is active.
src/scene/shader-lib/wgsl/chunks/lit/frag/lighting/shadowSoft.js Normalizes shadow-map sampling logic by flipping depths under reverse‑Z.
src/scene/shader-lib/wgsl/chunks/lit/frag/lighting/lightFunctionShadow.js Adjusts receiver depth/bias logic for reverse‑Z shadow compares.
src/scene/shader-lib/wgsl/chunks/lit/frag/clusteredLightShadows.js Flips clustered omni shadow compare Z for reverse‑Z.
src/scene/shader-lib/wgsl/chunks/common/vert/transform.js Fixes screenspace clip-space Z for reverse‑Z.
src/scene/shader-lib/wgsl/chunks/common/frag/screenDepth.js Updates linearize/delinearize helpers to account for reverse‑Z.
src/scene/shader-lib/wgsl/chunks/common/frag/pick.js Fixes ortho pick-depth interpretation under reverse‑Z.
src/scene/shader-lib/wgsl/chunks/common/frag/linearizeDepth.js Updates shared linearization helper for reverse‑Z.
src/scene/shader-lib/wgsl/chunks/common/frag/fog.js Flips hardware depth usage for fog under reverse‑Z.
src/scene/shader-lib/glsl/chunks/skybox/vert/skybox.js GLSL equivalent: skybox depth placement for reverse‑Z.
src/scene/shader-lib/glsl/chunks/particle/vert/particle_end.js GLSL equivalent: screenspace particle clip-space Z for reverse‑Z.
src/scene/shader-lib/glsl/chunks/particle/vert/particle_cpu_end.js GLSL equivalent: screenspace CPU particle clip-space Z for reverse‑Z.
src/scene/shader-lib/glsl/chunks/lit/frag/pass-shadow/litShadowMain.js GLSL equivalent: flip written shadow depth for reverse‑Z.
src/scene/shader-lib/glsl/chunks/lit/frag/lighting/shadowSoft.js GLSL equivalent: flip sampled depths / receiver depth for PCSS under reverse‑Z.
src/scene/shader-lib/glsl/chunks/lit/frag/lighting/lightFunctionShadow.js GLSL equivalent: adjust receiver depth/bias for reverse‑Z compares.
src/scene/shader-lib/glsl/chunks/lit/frag/clusteredLightShadows.js GLSL equivalent: flip clustered omni shadow compare Z for reverse‑Z.
src/scene/shader-lib/glsl/chunks/common/vert/transform.js GLSL equivalent: fix screenspace clip-space Z for reverse‑Z.
src/scene/shader-lib/glsl/chunks/common/frag/screenDepth.js GLSL equivalent: reverse‑Z-aware linearize/delinearize helpers.
src/scene/shader-lib/glsl/chunks/common/frag/pick.js GLSL equivalent: reverse‑Z-aware ortho pick depth.
src/scene/shader-lib/glsl/chunks/common/frag/linearizeDepth.js GLSL equivalent: shared linearization helper updated for reverse‑Z.
src/scene/shader-lib/glsl/chunks/common/frag/fog.js GLSL equivalent: fog depth flip for reverse‑Z.
src/scene/renderer/shadow-renderer.js Adjusts shadow viewport matrix Z remap for reverse‑Z hardware depth.
src/scene/renderer/renderer.js Passes device reverse‑Z state into shader projection transforms.
src/scene/immediate/immediate.js Places immediate-mode quads at the near plane under reverse‑Z so they keep expected depth behavior.
src/scene/camera.js Adds reverse‑Z WebGPU depth-range matrix and extends projection transform API.
src/platform/graphics/webgpu/webgpu-texture.js Flips WebGPU compare sampler function for reverse‑Z.
src/platform/graphics/webgpu/webgpu-render-target.js Inverts depth clear value for reverse‑Z when configuring render passes.
src/platform/graphics/webgpu/webgpu-render-pipeline.js Translates depth compare funcs + flips depth bias sign for reverse‑Z.
src/platform/graphics/webgpu/webgpu-graphics-device.js Stores the reverseZ option as isReverseZ and passes it into render-pass setup.
src/platform/graphics/webgpu/webgpu-clear-renderer.js Ensures clear-quad depth writes use reverse‑Z hardware convention.
src/platform/graphics/shader-definition-utils.js Injects REVERSE_Z define into generated shaders when enabled.
src/platform/graphics/graphics-device.js Documents/exposes isReverseZ on the base device type.
src/platform/graphics/graphics-device-create.js Documents options.reverseZ in the device creation API.
src/extras/gizmo/shape/shape.js Flips gizmo material depth parameter under reverse‑Z.
src/extras/gizmo/mesh-line.js Sets gizmo mesh-line depth parameter appropriately under reverse‑Z.
examples/src/examples/graphics/reverse-z.example.mjs Adds a new example demonstrating reverse‑Z precision benefits.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/scene/camera.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: graphics Graphics related issue enhancement Request for a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants