Use object to selectively mask other objects

I am trying to use a transparent object to mask some specific objects.
Taking inspiration from this post Use object to mask parts of others I made this fiddle Edit fiddle - JSFiddle - Code Playground
The fiddle has a torus, a cylinder and a cube, with the cylinder acting as a mask. Currently the cylinder hides all objects behind it, but I would like to hide only specific objects, i.e. hide the torus but not the cube.
Note, this works as intended if the cube is not set as transparent, but I need the cube to be transparent.

when you pair threejs with react it’s as easy as:

import { useStencil, Mask } from '@react-three/drei'

function SomeObject({ inverse = false }) {
  const stencil = useMask(1, inverse)
  return (
      <boxGeometry />
      <meshStandardMaterial {...stencil} />

  <Mask id={1} position={[0, 0, 0.95]}>
    <circleBufferGeometry args={[0.8, 64]} />
  <SomeObject inverse />

otherwise the code is here and you can adapt to vanilla: drei/Mask.tsx at 97fc7644d6ba13ce016b267cf8cbd6c243a31a95 · pmndrs/drei · GitHub

in short, the mask:

      colorWrite: false,
      depthWrite: false,
      stencilWrite: true,
      stencilRef: STENCILID,
      stencilFunc: THREE.AlwaysStencilFunc,
      stencilFail: THREE.ReplaceStencilOp,
      stencilZFail: THREE.ReplaceStencilOp,
      stencilZPass: THREE.ReplaceStencilOp,

any object that is affected by it:

    stencilWrite: true,
    stencilRef: STENCILID,
    stencilFunc: inverse ? THREE.NotEqualStencilFunc : THREE.EqualStencilFunc,
    stencilFail: THREE.KeepStencilOp,
    stencilZFail: THREE.KeepStencilOp,
    stencilZPass: THREE.KeepStencilOp,
1 Like

Make sure cube.renderOrder <= Masking_Object.renderOrder

1 Like

Hi there.
I think it is possible if you set opacity = 0 of meterial.

That simple :laughing: thank you!
In situation, my objects will normally have a renderOrder=0, so I cleared cylinder.renderOrder (so it’s 0) and set torus.renderOrder=1 and it behaves as intended.
There are some glitches when the cube intersects the cylinder due to transparency z-fighting. Incrementing the renderOrder of the torus and cylinder will prevent z-fighting.

1 Like

You are welcome,

To counter Z-Fighting, in this attachment I’m using polygonOffset.
Another solution is to increase the Y position of the red plane by small amount.

Z_Fighting.html (5.0 KB)