Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 3 months ago by AstralEngineer418

Stencil Capping Fails After Upgrading Three.js from v160 to v170

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

Hi

After upgrading from three.js v160 to v170, the capping of my clipping planes no longer works as expected. I use a capping plane based on PlaneGeometry, but now it appears everywhere rather than just where the stencils permit, and the stencils seem to be ignored. I've compared my approach with the examples on the three.js website (https://threejs.org/examples/?q=stencil#webgl_clipping_stencil) but haven’t identified any differences.

Here are my code details:

  1. I create a cross-section material (to cap the clipped surfaces):
JAVASCRIPT
const crossSectionMat = new THREE.MeshBasicMaterial({ color: hex, stencilWrite: true, stencilRef: 0, stencilFunc: THREE.NotEqualStencilFunc, stencilFail: THREE.ReplaceStencilOp, stencilZFail: THREE.ReplaceStencilOp, stencilZPass: THREE.ReplaceStencilOp, });
  1. I set the cross section’s onAfterRender function as follows:
JAVASCRIPT
crossSection.onAfterRender = function (renderer) { renderer.clearStencil(); };
  1. I create two stencils (front and back) using these materials:
JAVASCRIPT
const stencilBack = () => { const clippingPlane = CrossSection.getClippingPlane(); const stencilBackMat = new THREE.MeshBasicMaterial(); stencilBackMat.side = THREE.BackSide; stencilBackMat.depthWrite = false; stencilBackMat.depthTest = false; stencilBackMat.colorWrite = false; stencilBackMat.stencilWrite = true; stencilBackMat.stencilFunc = THREE.AlwaysStencilFunc; stencilBackMat.clippingPlanes = [clippingPlane]; stencilBackMat.stencilFail = THREE.IncrementWrapStencilOp; stencilBackMat.stencilZFail = THREE.IncrementWrapStencilOp; stencilBackMat.stencilZPass = THREE.IncrementWrapStencilOp; return stencilBackMat; }; const stencilFront = () => { const clippingPlane = CrossSection.getClippingPlane(); const stencilFrontMat = new THREE.MeshBasicMaterial(); stencilFrontMat.side = THREE.FrontSide; stencilFrontMat.depthWrite = false; stencilFrontMat.depthTest = false; stencilFrontMat.colorWrite = false; stencilFrontMat.stencilWrite = true; stencilFrontMat.stencilFunc = THREE.AlwaysStencilFunc; stencilFrontMat.clippingPlanes = [clippingPlane]; stencilFrontMat.stencilFail = THREE.DecrementWrapStencilOp; stencilFrontMat.stencilZFail = THREE.DecrementWrapStencilOp; stencilFrontMat.stencilZPass = THREE.DecrementWrapStencilOp; return stencilFrontMat; };
  1. I integrate the stencils with an object’s geometry as follows:
JAVASCRIPT
const createStencil = (obj) => { if (!obj.geometry) return; const geometry = obj.geometry; const stencil = new THREE.Group(); stencil.name = "stencilGroup"; // back faces const mat0 = Material.stencilBack(); const mesh0 = new THREE.Mesh(geometry, mat0); mesh0.name = "stencilMesh0"; stencil.add(mesh0); // front faces const mat1 = Material.stencilFront(); const mesh1 = new THREE.Mesh(geometry, mat1); mesh1.name = "stencilMesh1"; stencil.add(mesh1); obj.add(stencil); };
  1. I apply the stencils when a button is clicked:
JAVASCRIPT
renderer.stencil = true; renderer.localClippingEnabled = true; crossSection.visible = true;

Any insights or suggestions on what might have changed between versions would be greatly appreciated!

4

Comments 0

Answers 0

Views 68

0 Answers

Discussion

No comments yet.