-
-
Notifications
You must be signed in to change notification settings - Fork 36.3k
TSL: Unused If() branch sampling a texture breaks the texture's direct usage in output #33295
Copy link
Copy link
Open
Labels
Description
Description
When a depth texture is sampled directly in the TSL output AND also sampled inside an If() branch gated by a runtime uniform, the direct output sample breaks when the If() branch is not taken (uniform = 0).
The unused If() branch should have no effect on the output — the depth texture is used unconditionally in the return value. However, the presence of the disabled branch causes the depth texture to read as a constant/incorrect value.
Removing the If() block entirely restores correct behavior.
Reproduction Steps
- Create a render target with a
DepthTexture - Render a scene to the render target
- In a fullscreen quad's TSL
colorNode, sample the depth texture directly in the output - Add an
If()branch gated by auniform(0.0)that also samples the same depth texture - Observe the depth texture output is broken despite being used unconditionally
- Either remove the
If()block or set the uniform to1.0— rendering is correct again
Code
import * as THREE from "three/webgpu";
import { Fn, texture, screenUV, vec4, float, uniform, If, step } from "three/tsl";
async function init() {
const renderer = new THREE.WebGPURenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
await renderer.init();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.z = 3;
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x222222);
scene.add(new THREE.Mesh(new THREE.SphereGeometry(), new THREE.MeshBasicMaterial()));
const rt = new THREE.RenderTarget(window.innerWidth, window.innerHeight);
rt.depthTexture = new THREE.DepthTexture(window.innerWidth, window.innerHeight);
const featureEnabled = uniform(0.0);
const colorNode = Fn(() => {
const depth = texture(rt.depthTexture, screenUV);
const extra = float(0.0).toVar();
// BUG: This unused If() block breaks the depth sample in the return
If(featureEnabled.greaterThan(0.5), () => {
extra.assign(depth.r);
});
return vec4(step(float(1.0).sub(depth.r), float(0.0)), 0, 0, 1.0);
})();
const quadMat = new THREE.MeshBasicNodeMaterial();
quadMat.colorNode = colorNode;
const quadScene = new THREE.Scene();
quadScene.add(new THREE.Mesh(new THREE.PlaneGeometry(2, 2), quadMat));
const quadCam = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
renderer.setAnimationLoop(() => {
renderer.setRenderTarget(rt);
renderer.render(scene, camera);
renderer.setRenderTarget(null);
renderer.render(quadScene, quadCam);
});
}
init();Live Example
https://jsfiddle.net/w8v0Lfx2/3/
Version
r183.2
Device
Desktop
Browser
Chrome
OS
MacOS
Reactions are currently unavailable