Three.js usage with stencil buffer

前端 未结 2 557
后悔当初
后悔当初 2021-01-07 14:48

I can\'t get the following to draw the scene into the shape created as a stencil mask. Instead the code just seems to render the stencil itself as a black object.

ht

相关标签:
2条回答
  • 2021-01-07 15:12

    Through trial and error I updated my code to this and it now works. Clearing the depth buffer seems particularly important so I guess my mask must have been hiding the more distant floor fragments.

    // Render the scene
    function fla_render() {
    
        floor_align.renderer.clear();
    
        // Background
        //floor_align.renderer.render(floor_align.scene, floor_align.camera);
    
        floor_align.renderer.clearDepth();
    
        var gl = floor_align.renderer.domElement.getContext('webgl') || floor_align.renderer.domElement.getContext('experimental-webgl');
    
        // Clear the stencil buffer
        gl.clearStencil(0);
        gl.clear(gl.STENCIL_BUFFER_BIT);
    
        // Replacing the values at the stencil buffer to 1 on every pixel we draw
        gl.stencilFunc(gl.ALWAYS, 1, 1);
        gl.stencilOp(gl.KEEP, gl.REPLACE, gl.REPLACE);
    
        // Disable color (u can also disable here the depth buffers)
        gl.colorMask(false, false, false, false);
    
        // Write to stencil
        gl.enable(gl.STENCIL_TEST);
    
        // Floor Mask (Create a stencil that we render the next pass into)
        floor_align.renderer.render(floor_align.maskScene, floor_align.maskCamera);
    
        // Telling the stencil now to draw/keep only pixels that equals 1 - which we set earlier
        gl.stencilFunc(gl.EQUAL, 1, 1);
        gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
    
        // Clear depth buffer (seems important)
        floor_align.renderer.clearDepth();
    
        // Enable color
        gl.colorMask(true, true, true, true);
    
        // Render a floor pass
        floor_align.renderer.render(floor_align.scene, floor_align.camera);
    
        // Disable stencil test;
        gl.disable(gl.STENCIL_TEST);
    
    }
    
    0 讨论(0)
  • 2021-01-07 15:30

    Accepted answer don't work on latest threejs. If anyone interested, here's an up-to-date version that works (using r111):

    
            gl.enable(gl.STENCIL_TEST);
            gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
    
            //renderer.clear(); <-- works without this too
    
            gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
            gl.stencilMask(0xFF);
            renderer.render(maskScene, camera);
    
            gl.stencilFunc(gl.EQUAL, 1, 0xFF);
            gl.stencilMask(0x00);
    
            renderer.render(scene, camera);
            gl.stencilMask(0xFF);
            gl.disable(gl.STENCIL_TEST);
    

    Also in my case I didn't disable auto-clear and it still works.

    0 讨论(0)
提交回复
热议问题