You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js中如何通过平面将3D模型切割为两个独立部分?

Three.js 平面切割3D几何体为独立两部分落地实现方案

之前参考的Y平面裁剪方案无法得到预期效果,核心原因是材质层的clippingPlanes只做渲染层面的像素丢弃,不会真的把几何体拆成两个独立的网格实体,自然拿不到可单独操作的两部分模型。
要实现真正的几何拆分,直接按下面的方案做,稳定性和效果都能达到参考要求:
3D平面切割效果参考

核心实现思路

  • 放弃渲染裁剪方案,直接对几何体的三角面数据做空间计算,优先用成熟的实体布尔运算库完成切割,避免手写几何相交逻辑出现破面、法线错误问题
  • 切割完成后自动补全断面封盖,保证切出来的两个模型都是封闭实体,不会出现空心漏面

可直接复用的实现步骤

  1. 依赖准备
    引入Three.js生态维护的three-bvh-csg库,这个库用BVH结构加速布尔运算,比旧版CSG库性能高几个量级,切割复杂模型也不会卡顿。
  2. 基础初始化
    import * as THREE from 'three';
    import { Brush, Evaluator, SUBTRACTION } from 'three-bvh-csg';
    // 初始化布尔运算计算器
    const evaluator = new Evaluator();
    
  3. 切割逻辑实现
    // 把待切割的原模型转为布尔运算支持的Brush类型
    const originalModel = new Brush(targetModel.geometry, targetModel.material);
    // 定义切割平面,示例为Y=2位置的水平切割面,可自行修改法向量实现任意方向切割
    const cutPlane = new THREE.Plane(new THREE.Vector3(0, 1, 0), -2);
    // 生成尺寸足够覆盖待切模型的切割刀具,厚度设为极小值即可
    const cutterGeo = new THREE.BoxGeometry(200, 0.001, 200);
    // 将刀具对齐到切割平面位置
    cutterGeo.translate(0, cutPlane.constant, 0);
    const cutter = new Brush(cutterGeo);
    
    // 计算得到平面正侧的模型部分
    cutter.position.y = -1000;
    const partPositive = evaluator.evaluate(originalModel, cutter, SUBTRACTION);
    // 计算得到平面负侧的模型部分
    cutter.position.y = 1000;
    const partNegative = evaluator.evaluate(originalModel, cutter, SUBTRACTION);
    
    // 两个部分都是独立的Mesh对象,可单独添加材质、移动、绑定交互
    scene.add(partPositive, partNegative);
    

避坑提示

  • 切割前先对原模型几何体执行geometry.mergeVertices()、geometry.computeVertexNormals(),避免因顶点重复、法线缺失导致切割后出现黑面、破面
  • 切割刀具的尺寸只要比待切模型的包围盒大即可,不用设得过大,避免不必要的性能消耗
  • 如果需要给断面单独上材质,可以在布尔运算完成后遍历两个模型的几何体,给断面生成的三角面设置独立的材质分组
  • 带骨骼动画、变形动画的模型不适合直接做静态几何切割,需要先把当前帧的蒙皮结果烘焙为静态几何体再执行切割

内容的提问来源于stack exchange,提问作者Kamenskyh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:39:14