Skip to content

WebGPURenderer: Interference between LinearSRGBColorSpace and z-buffer in WebGL2 backend of r173 #30526

@boytchev

Description

@boytchev

Description

When the WebGL2 backend of WebGPURenderer with a LinearSRGBColorSpace is used in Three.js r173, the z-buffering appears broken - i.e. objects are drawn as if no z-buffering is used, or as if depth testing/writing is turned off. The problem does not appear if any of these things is done:

  • an older release is used, e.g. r172
  • a WebGPU browser is used (thus no fallback to WebGL2 backend)
  • SRGBColorSpace is used instead of LinearSRGBColorSpace

A side node: is there a way to force WebGPURenderer to use WebGL2 backend for testing/debug purposes? Currently I have to switch between two browsers - Chrome for WebGPU and Firefox for WebGL2 backend.

Reproduction steps

  1. Create a scene with two objects that intersect
  2. Use WebGPURenderer from r173 with outputColorSpace set to LinearSRGBColorSpace
  3. Run in a non-WebGPU browser, so the WebGL2 backend is used
  4. One of the objects will be draw on top of the other, without expected intersection

Code

Import maps:

<head>
  <script type="importmap">
  {
    "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@0.173.0/build/three.webgpu.min.js"
    }
  }
</script>
</head>

JS code:

import * as THREE from "three";

var camera = new THREE.PerspectiveCamera( 60, innerWidth/innerHeight );
    camera.position.set( 0, 0, 10 );

var scene = new THREE.Scene();
    scene.add(
          new THREE.Mesh(
                new THREE.BoxGeometry( 2, 2, 2 ),
                new THREE.MeshBasicNodeMaterial( {color: 'red'} )
          ),
          new THREE.Mesh(
                new THREE.BoxGeometry( 4, 1, 1 ),
                new THREE.MeshBasicNodeMaterial( {color: 'tan'} )
          )	
    );		

var renderer = new THREE.WebGPURenderer( );
    renderer.setSize( innerWidth, innerHeight );
    document.body.appendChild( renderer.domElement );
    renderer.setAnimationLoop( animationLoop );

function animationLoop( t ) {

    scene.rotation.y = t/1000;
    renderer.renderAsync( scene, camera );

}

// remove next line to show well intersecting boxes
renderer.outputColorSpace = THREE.LinearSRGBColorSpace;

Live example

Screenshots

Wrong rendering: overlapping boxes with LinearSRGBColorSpace

Image

Correct rendering: intersecting boxes without LinearSRGBColorSpace

Image

Version

r173

Device

Desktop

Browser

Firefox

OS

Windows

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions