How to apply a color-only ShaderPass while preserving depth buffer for a later RenderPass?

Hi, I’m working with EffectComposer and multiple RenderPass in three.js, and I ran into a depth-buffer issue when combining a ShaderPass with additional scenes.

Here’s a minimal setup:

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.autoClear = true;

const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);

const mainScene = new THREE.Scene();
const overlayScene = new THREE.Scene(); // drawn on top of mainScene

// ... populate mainScene / overlayScene with generic meshes & materials ...

const composer = new EffectComposer(renderer);

const passMain = new RenderPass(mainScene, camera);
passMain.clear = true;
composer.addPass(passMain);

const passOverlay = new RenderPass(overlayScene, camera);
passOverlay.clear = false; // do not clear, draw over
composer.addPass(passOverlay);

// Generic ShaderPass (color-only)
const GenericShader = {
  uniforms: {
    tDiffuse: { value: null },
    someParam: { value: 0.0 },
  },
  vertexShader: /* glsl */`
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: /* glsl */`
    uniform sampler2D tDiffuse;
    uniform float someParam;
    varying vec2 vUv;

    void main() {
      vec4 color = texture2D(tDiffuse, vUv);

      // example color modification
      color.rgb *= (1.0 + someParam);

      gl_FragColor = color; // color-only; do not touch gl_FragDepth
    }
  `
};

const shaderPass = new ShaderPass(GenericShader);
composer.addPass(shaderPass);

// Later I want to render another scene AFTER the ShaderPass:
const extraScene = new THREE.Scene();
// ... populate extraScene ...

Goal
After the ShaderPass, I want to render extraScene that:

  1. uses the depth buffer from the first two scenes for correct depth testing, and

  2. is not affected by the ShaderPass color modification.


What I tried

  1. Custom ShaderPass (color-only)
    I kept the fragment shader color-only (no gl_FragDepth writes). This avoids overwriting depth, but I still can’t make a later RenderPass consume the earlier depth reliably.

  2. Manual render after composer

    composer.render();
    renderer.autoClear = false;
    renderer.clearDepth();          // if I clear depth, extraScene renders on top
    renderer.render(extraScene, camera);
    
    

    This renders, but clearing depth defeats the purpose.


Question
What’s the recommended way in three.js to:

  • apply a color-only ShaderPass,

  • preserve the depth buffer from previous passes,

  • and then render another scene that uses that preserved depth (while not being color-modified)?

Is there an existing pattern in EffectComposer to keep and reuse the depth attachment, or do I need a custom multi-target FBO / manual MRT setup?