Post processing on parts of a scene

I am doing post processing of a scene. I am using the depth buffer to mark the outline of the rendered objects (the actual post processing is more complex – I have simplified it to illustrate the example).

I’d like to skip post processing on “cube2”, whoever. How can I do that?

    import * as THREE from 'https://unpkg.com/three@0.126.1/build/three.module.js';
    import { OrbitControls } from 'https://unpkg.com/three@0.126.1/examples/jsm/controls/OrbitControls.js';
    import { EffectComposer } from 'https://unpkg.com/three@0.126.1/examples/jsm/postprocessing/EffectComposer.js';
    import { RenderPass } from 'https://unpkg.com/three@0.126.1/examples/jsm/postprocessing/RenderPass.js';
    import { ShaderPass } from 'https://unpkg.com/three@0.126.1/examples/jsm/postprocessing/ShaderPass.js';

    // scene, camera, and renderer setup
    let scene = new THREE.Scene();
    let aspect = window.innerWidth / window.innerHeight;
    let camera = new THREE.OrthographicCamera(-aspect, aspect, 1, -1, 0.1, 1000);
    let renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // controls
    let controls = new OrbitControls(camera, renderer.domElement);
    controls.addEventListener('change', render);

    // objects
    let geometry1 = new THREE.BoxGeometry(1, 1, 1);
    let material1 = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    let cube = new THREE.Mesh(geometry1, material1);
    scene.add(cube);

    let geometry2 = new THREE.SphereGeometry(0.3, 32, 32);
    let material2 = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    let sphere = new THREE.Mesh(geometry2, material2);
    sphere.position.z = 2;
    scene.add(sphere);

    let geometry3 = new THREE.BoxGeometry(0.8, 0.1, 0.1);
    let material3 = new THREE.MeshBasicMaterial({ color: 0xff0000 });
    let cube2 = new THREE.Mesh(geometry3, material3);
    cube2.position.z = 3;
    scene.add(cube2);

    // camera position
    camera.position.z = 5;

    // depth texture setup
    let target = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
    target.depthTexture = new THREE.DepthTexture();
    target.depthTexture.format = THREE.DepthFormat;
    target.depthTexture.type = THREE.UnsignedShortType;

    let outlineShader = {
        uniforms: {
            rgbBuffer: { type: "t", value: null },
            depthBuffer: { type: "t", value: null }
        },
        vertexShader: `
        varying vec2 vUv;
        void main() {
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
        }
    `,
        fragmentShader: `
        varying vec2 vUv;
        uniform sampler2D rgbBuffer;
        uniform sampler2D depthBuffer;

        void main() {
            float depth = texture2D(depthBuffer, vUv).x;
            float depth1 = texture2D(depthBuffer, vUv + vec2(0.002, 0)).x;
            float depth2 = texture2D(depthBuffer, vUv + vec2(0, 0.002)).x;

            vec4 color = texture2D(rgbBuffer, vUv);
            bool isEdge = (abs(depth - depth1) > 0.0001 || abs(depth - depth2) > 0.0001) && depth != 1.0 && depth1 != 1.0 && depth2 != 1.0;
        
            gl_FragColor = vec4(color.xyz * (1.0 - (isEdge ? 0.5 : 0.0)), 1.0);
        }
    `,
    };

    
    let composer = new EffectComposer(renderer, target);
    let renderPass = new RenderPass(scene, camera);

    let shaderPass = new ShaderPass(outlineShader);
    shaderPass.uniforms['rgbBuffer'].value = composer.renderTarget1.texture;
    shaderPass.uniforms['depthBuffer'].value = target.depthTexture;
    shaderPass.renderToScreen = true;

    composer.addPass(renderPass);
    composer.addPass(shaderPass);

    function render() {
        renderer.setRenderTarget(target);
        renderer.render(scene, camera);
        renderer.setRenderTarget(null);

        composer.render();
    }

    render();

better use GitHub - pmndrs/postprocessing: A post processing library that provides the means to implement image filter effects for three.js. instead of jsm/effectcomposer. some of its effect have selection inbuilt, outline is one example. it is also a lot faster.

i only have a react example

but it’s the same in the vanilla outline effect pass, the property is called “selection” OutlineEffect | postprocessing

ps, even with your custom shader you are better off with postpro because selection is something you can just integrate and the library will take care of managing it.

1 Like