首页 > 解决方案 > threejs 和模板缓冲区用作掩码

问题描述

我无法让模板缓冲区与threejs一起使用。有人可以向我解释我需要改变什么。

黄色平面将用作蒙版,我们应该只看到与黄色平面重叠的绿色平面。

threejs 上的示例显示了用于剪切平面的模板缓冲区,这并不是我所需要的。

import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.114/build/three.module.js";

var _renderer;
var _canvas;
var _camera;
var _scene;

function setupRender() {

    _canvas = document.getElementById("mycanvas");

    let context = _canvas.getContext("webgl", { preserveDrawingBuffer: false });

    window._r = _renderer = new THREE.WebGLRenderer({
        context: context,
        canvas: _canvas,
        stencil: true,
        premultipliedAlpha: false,
    });

    _renderer.setPixelRatio(window.devicePixelRatio);

    _renderer.autoClear = true;
    _renderer.autoClearColor = true;
    _renderer.autoClearDepth = true;
    _renderer.autoClearStencil = true;

    window.addEventListener('resize', onWindowResize);
}

function create() {
    _camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
    _camera.position.z = 400;

    _scene = new THREE.Scene();

    createPlaneYellow();
    createPlaneGreen();

    onWindowResize();
}

function createPlaneYellow(){
    const geometry = new THREE.PlaneGeometry( 100, 100 );
    const material = new THREE.MeshBasicMaterial( {
        color: 0xffff00, 
        side: THREE.DoubleSide,
        //colorWrite : false,
        depthWrite : false,
        depthTest :false,

        stencilWrite: true,
        stencilWriteMask: 0xff,                                         // values gets AND with stencil buffer before write
        
        // these 3 variable are used for glStenilFunc(func, ref, mask)
        stencilFunc : THREE.AlwaysStencilFunc,                          // which fragments are passes or is discarded
        stencilRef : 1,                                                 // value for the stencil test
        stencilFuncMask: 0xff,                                          // specifies a mask that is ANDed with both the reference value and the stored stencil value before the test compares them. Initially set to all 1s
        
        // these 3 variables are used for glStencilOp(fail, zfail, zpass)
        stencilFail: THREE.KeepStencilOp,                           // The stencil value is replaced with the reference value set with glStencilFunc
        stencilZFail: THREE.KeepStencilOp,
        stencilZPass: THREE.ReplaceStencilOp
        
    } );


    const plane = new THREE.Mesh( geometry, material );
    _scene.add( plane );    
}

function createPlaneGreen(){
    const geometry = new THREE.PlaneGeometry( 100, 100 );
    const material = new THREE.MeshBasicMaterial({
        color: 0x00ff00, 
        side: THREE.DoubleSide,
        depthWrite : true,
        depthTest :true,

        stencilWrite: true,
        stencilWriteMask: 0xff,                 // <---- don't think this is necessary when we are not writting here

        stencilFunc : THREE.EqualStencilFunc,
        stencilRef: 0,
        stencilFuncMask: 0xff,

        stencilFail: THREE.KeepStencilOp,
        stencilZFail: THREE.KeepStencilOp,
        stencilZPass: THREE.KeepStencilOp
    });


    const plane = new THREE.Mesh( geometry, material );
    plane.position.x = 50;
    plane.position.y = -50;
    _scene.add( plane );    
}

function onWindowResize() {

    _camera.aspect = window.innerWidth / window.innerHeight;
    _camera.updateProjectionMatrix();

    _renderer.setSize( window.innerWidth, window.innerHeight );

}

function update() {
    requestAnimationFrame(update);
    _renderer.render(_scene, _camera);
}

window.onload = () => {

    setupRender();
    create();
    update();
};

标签: three.jsstencil-buffer

解决方案


推荐阅读