I’m using the example of the following link, https://github.com/mrdoob/three.js/blob/129635bdb5cbfa11f1b31522889846e862da43d0/examples/webgl_clipping_stencil.html to implement capping the meshes.
My gltf file includes more than 20000 meshes, so when I apply x,y,z clipping planes for each mesh, the rendering is pretty slow and the FPS on the stats UI indicates 4 ~ 6 FPS.
Is there a way to increase the performance?
This is my loading gltf code.
let object, planeObjects;
function initLoaders(renderer, workerLimit = undefined) {
let ktx2Loader = new KTX2Loader()
.setTranscoderPath("libs/basis/")
.detectSupport(renderer);
if (workerLimit) ktx2Loader.setWorkerLimit(workerLimit);
let dracoLoader = new DRACOLoader().setDecoderPath("libs/draco/");
if (workerLimit) dracoLoader.setWorkerLimit(workerLimit);
const gltfLoader = new GLTFLoader()
.setCrossOrigin("anonymous")
.setDRACOLoader(dracoLoader)
.setKTX2Loader(ktx2Loader)
.setMeshoptDecoder(MeshoptDecoder);
return gltfLoader;
}
loader.load("./mydata.glb", (gltf) => {
const fscene = gltf.scene || gltf.scenes[0];
object = new THREE.Group();
scene.add(object);
// Set up clip plane rendering
planeObjects = [];
const planeGeoms = [
new THREE.PlaneGeometry(bodySize[2], bodySize[1]),
new THREE.PlaneGeometry(bodySize[0], bodySize[2]),
new THREE.PlaneGeometry(bodySize[0], bodySize[1]),
];
fscene.traverse((child) => {
if (child.isMesh) {
for (let i = 0; i < 3; i++) {
const poGroup = new THREE.Group();
const plane = planes[i];
const stencilGroup = createPlaneStencilGroup(
child.geometry,
plane,
i + 1
);
// plane is clipped by the other clipping planes
const planeMat = new THREE.MeshStandardMaterial({
color: "#611E1E",
metalness: 0.1,
roughness: 0.75,
clippingPlanes: planes.filter((p) => p !== plane),
stencilWrite: true,
stencilRef: 0,
stencilFunc: THREE.NotEqualStencilFunc,
stencilFail: THREE.ReplaceStencilOp,
stencilZFail: THREE.ReplaceStencilOp,
stencilZPass: THREE.ReplaceStencilOp,
});
const po = new THREE.Mesh(planeGeoms[i], planeMat);
po.onAfterRender = function (renderer) {
renderer.clearStencil();
};
po.renderOrder = i + 1.1;
object.add(stencilGroup);
poGroup.add(po);
planeObjects.push(po);
scene.add(poGroup);
}
child.material.clippingPlanes = planes;
child.material.shadowSide = THREE.DoubleSide;
child.material.clipShadows = true;
child.material.needsUpdate = true;
object.add(child);
}
});
function animate() {
requestAnimationFrame(animate);
for (let i = 0; i < planeObjects.length; i++) {
const plane = planes[i % 3];
const po = planeObjects[i];
plane.coplanarPoint(po.position);
po.lookAt(
po.position.x - plane.normal.x,
po.position.y - plane.normal.y,
po.position.z - plane.normal.z
);
}
renderer.render(scene, camera);
}