Three.js Local Clipping Planes on Specific Material

In Three.js, clipping planes allow you to cut away portions of 3D objects to reveal their inner structures. While global clipping affects every object in a scene, local clipping applies selectively to specific materials. This article provides a direct, step-by-step guide on how to create clipping planes, apply them to a targeted material, and configure the WebGL renderer to enable local clipping in your 3D application.

Step 1: Enable Local Clipping on the Renderer

By default, Three.js does not calculate local clipping planes because it requires extra processing power. You must explicitly enable this feature on your WebGLRenderer instance.

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Enable local clipping planes
renderer.localClippingEnabled = true;

Step 2: Define the Clipping Plane

A clipping plane is defined using the THREE.Plane class. It requires a normal vector (which direction the plane faces) and a constant (the distance from the origin along the normal vector).

// Create a plane that cuts horizontally, facing downwards
const localPlane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.5);

In this example, any part of the geometry that lies on the positive side of the plane (above \(y = 0.5\)) will be clipped (rendered invisible).

Step 3: Apply the Plane to a Specific Material

To restrict the clipping to a single object or a specific set of objects, assign the clipping plane to the clippingPlanes property of their material. This property accepts an array of planes, allowing you to use multiple clipping boundaries on a single material.

const material = new THREE.MeshStandardMaterial({
  color: 0x00ff00,
  roughness: 0.4,
  clippingPlanes: [localPlane], // Apply the local clipping plane here
  clipShadows: true             // Optional: Crops the shadows cast by the clipped object
});

By setting clipShadows: true, Three.js will also clip the shadows cast by the object, maintaining visual accuracy.

Step 4: Create and Add the Mesh to the Scene

Now, apply the material to your geometry. Only the mesh using this specific material will be affected by the clipping plane. Other meshes in the scene using different materials will remain fully intact.

const geometry = new THREE.TorusKnotGeometry(0.4, 0.15, 120, 16);
const clippedMesh = new THREE.Mesh(geometry, material);
scene.add(clippedMesh);

// This standard mesh will NOT be clipped
const normalMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const normalMesh = new THREE.Mesh(geometry, normalMaterial);
normalMesh.position.x = 2;
scene.add(normalMesh);

Step 5: (Optional) Animating the Clipping Plane

You can dynamically adjust the position of the clipping plane in your animation loop by modifying its constant property.

function animate() {
  requestAnimationFrame(animate);

  // Animate the plane up and down over time
  localPlane.constant = Math.sin(Date.now() * 0.002) * 0.8;

  renderer.render(scene, camera);
}
animate();