如何通过dat.GUI控件动态调整Three.js拉伸网格长宽高
Three.js ExtrudeGeometry 尺寸GUI控制实现方案
核心实现逻辑:不需要手动映射修改Shape下零散的curve属性,参数变更时直接重建几何体替换即可,这是这类参数化拉伸模型最稳妥、维护成本最低的实现方式,性能完全满足常规交互需求。
实现步骤
- 把需要调整的尺寸参数(长x_len、宽y_len、拉伸深度z_len、边框厚度thickness)统一存在一个配置对象中,方便GUI直接绑定
- 将Shape路径绘制、拉伸几何体生成的逻辑抽为独立的更新函数,每次参数变动时执行:
- 按最新参数重新绘制带内挖空的Shape路径
- 生成新的ExtrudeGeometry实例
- 调用
dispose()方法释放旧几何体占用的显存,避免内存泄漏 - 给场景中已有的网格对象替换新的几何体
- 直接将三个尺寸参数绑定到dat.GUI控件,值变更时触发更新函数即可
核心修改代码
首先把网格实例、参数配置提到外层作用域,抽离更新函数:
let frameMesh; // 统一管理可调参数 const frameParams = { x_len: 12, y_len: 8, z_len: 1, thickness: 0.5 }; // 几何体更新逻辑 function updateFrameGeometry() { const { x_len, y_len, z_len, thickness } = frameParams; // 绘制新路径 const shape = new THREE.Shape(); shape.moveTo(0, 0); shape.lineTo(0, y_len); shape.lineTo(x_len, y_len); shape.lineTo(x_len, 0); shape.lineTo(0, 0); // 绘制内框挖空 shape.lineTo(thickness, thickness); shape.lineTo(x_len - thickness, thickness); shape.lineTo(x_len - thickness, y_len - thickness); shape.lineTo(thickness, y_len - thickness); shape.lineTo(thickness, thickness); const extrudeSettings = { steps: 2, depth: z_len, bevelEnabled: false }; const newGeo = new THREE.ExtrudeGeometry(shape, extrudeSettings); // 释放旧几何体显存 if (frameMesh.geometry) frameMesh.geometry.dispose(); // 替换新几何体 frameMesh.geometry = newGeo; }
初始化网格、绑定GUI控件:
// 场景初始化完成后,创建框体网格 const frameMat = new THREE.MeshPhongMaterial({ color: '#CA8' }); frameMesh = new THREE.Mesh(new THREE.BufferGeometry(), frameMat); scene.add(frameMesh); // 初始化生成默认尺寸的框体 updateFrameGeometry(); // GUI初始化部分添加尺寸控制 const gui = new dat.GUI(); gui.add(frameParams, 'x_len', 1, 40, 0.1).onChange(updateFrameGeometry); gui.add(frameParams, 'y_len', 1, 40, 0.1).onChange(updateFrameGeometry); gui.add(frameParams, 'z_len', 0.1, 10, 0.1).onChange(updateFrameGeometry); // 原有灯光、轨道控制器、渲染循环逻辑保持不变即可
方案说明
不推荐手动修改shape.curves下零散坐标点的原因:
- 修改曲线坐标后,还需要手动触发生几何体顶点更新、法线重算,遗漏任意一步都会出现渲染错误
- 后续如果需要加倒角、调整边框厚度、修改路径形状,多属性映射的逻辑会快速变得难以维护
- 这类简单二维拉伸的几何体重建开销极低,常规交互场景下完全不会出现卡顿,性价比远高于维护复杂的属性绑定逻辑
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

