I cannot get the stencil buffer to work with threejs. can someone please explain to me what I need to changed.
The yellow plane is to be used as a mask and we should only see the green plane where it overlaps the yellow plane.
The example on threejs shows the stencil buffer being used for clip planes, which is not exactly what I need.
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();
};