Background
In my previous post, I mention to create stencil seal on the object. In that, invisible planes crop the object off. You can see the example in this site quickly as I referred to the code. This means something inside the content come out by slashing it. While learning Three.js from the example, I figured out that the resulting image looked like Japanese animation called GANTZ. You can see my inspired vision in the following official tweet.
In the above scene, a guy’s body is being cut off and it is gradually fading out. The astonishing effect got me a significant impact. Therefore I determined to demonstrate such an effect using Three.js.
Load Human 3D model
First of all, I loaded a 3D model and textures that are in the examples in Three.js repository. Thanks to the repository, I can get a realistic human model.
var textureLoader = new THREE.TextureLoader();
var loader = new GLTFLoader();
loader.load('https://threejs.org/examples/models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) {
mesh = gltf.scene.children[0];
mesh.material = new THREE.MeshPhongMaterial({
specular: 0x111111,
map: textureLoader.load('https://threejs.org/examples/models/gltf/LeePerrySmith/Map-COL.jpg'),
specularMap: textureLoader.load('https://threejs.org/examples/models/gltf/LeePerrySmith/Map-SPEC.jpg'),
normalMap: textureLoader.load('https://threejs.org/examples/models/gltf/LeePerrySmith/Infinite-Level_02_Tangent_SmoothUV.jpg'),
shininess: 25,
});
})
Prepare Clipping planes
After the 3D model has loaded, I created invisible planes so that they can clip the 3D model overlapped in. The meat of the creation is in Material. That procedure to create is like the following a couple code:
// Set up clip plane rendering
planeObjects = [];
var planeGeom = new THREE.PlaneBufferGeometry(100, 100);
for (var i = 0; i < 3; i++) {
var poGroup = new THREE.Group();
var plane = planes[i];
var stencilGroup = createPlaneStencilGroup(mesh.geometry, plane, i + 1);
// plane is clipped by the other clipping planes
var planeMat =
new THREE.MeshStandardMaterial({
color: 0xE91E63,
clippingPlanes: planes.filter(p => p !== plane),
stencilWrite: true,
stencilRef: 0,
stencilFunc: THREE.NotEqualStencilFunc,
stencilFail: THREE.ReplaceStencilOp,
stencilZFail: THREE.ReplaceStencilOp,
stencilZPass: THREE.ReplaceStencilOp,
});
var po = new THREE.Mesh(planeGeom, planeMat);
po.onAfterRender = function (renderer) {
renderer.clearStencil();
};
po.renderOrder = i + 1.1;
object.add(stencilGroup);
poGroup.add(po);
planeObjects.push(po);
scene.add(poGroup);
}
var material = new THREE.MeshStandardMaterial({
map: textureLoader.load('https://threejs.org/examples/models/gltf/LeePerrySmith/Map-COL.jpg'),
specularMap: textureLoader.load('https://threejs.org/examples/models/gltf/LeePerrySmith/Map-SPEC.jpg'),
normalMap: textureLoader.load('https://threejs.org/examples/models/gltf/LeePerrySmith/Infinite-Level_02_Tangent_SmoothUV.jpg'),
clippingPlanes: planes,
});
To meet requisition for clipping object, I have to turn on the property, localClippingEnabled
supported by WEBGLRenderer otherwise clipping would fail.
renderer.localClippingEnabled = true;
You can see how the invisible planes cut the 3D human model off.
![]() |
![]() |
![]() |
Conclusion
As the invisible planes is likewise composed of Material, a shader material would be fine, too. Using them, the cutting face can colour more cool effects such as GANTZ animation.