THREE.JS中调整立方体高度时如何避免向负Y方向扩展
Three.js立方体仅向正Y方向调整高度的解决方案
在Three.js场景中添加立方体后,通过增大BoxGeometry构造函数的Y轴参数调整高度时,立方体会同时向正负Y两个方向扩展,不符合仅向正Y方向增高的需求。当前实现代码如下:
var cubeGeometry2 = new THREE.BoxGeometry(10, 25, 5); var cubeMaterial2 = new THREE.MeshBasicMaterial({ color: '#5A5A5A', wireframe: false }); var cube3 = new THREE.Mesh(cubeGeometry2, cubeMaterial2); console.log(cubeGeometry2) cube3.position.set(25, 5.5, -12); scene.add(cube3);
我尝试了一个非常规的解决办法,通过遍历顶点将所有负Y方向的顶点置为0:
// 先查看顶点数据 console.log(cubeGeometry2) // 遍历顶点列表,将所有Y值为负的顶点置为0 for(let i = 0;i < cube3.geometry.vertices.length;i++){ if(cube3.geometry.vertices[i].y < 0){ cube3.geometry.vertices[i].y = cube3.geometry.vertices[i].y * 0 } }
更规范的解决方案
方法一:偏移几何体顶点
BoxGeometry的顶点以原点为中心对称分布,要实现仅向正Y方向扩展,可直接将所有顶点的Y坐标加上原高度的一半,这样立方体底部会对齐Y=0位置,增高时仅向上扩展:
const cubeGeometry2 = new THREE.BoxGeometry(10, 25, 5); // 原高度的一半为12.5,偏移所有顶点Y坐标 cubeGeometry2.vertices.forEach(vertex => { vertex.y += 12.5; }); // 标记顶点数据已更新,确保渲染生效 cubeGeometry2.verticesNeedUpdate = true; const cubeMaterial2 = new THREE.MeshBasicMaterial({ color: '#5A5A5A', wireframe: false }); const cube3 = new THREE.Mesh(cubeGeometry2, cubeMaterial2); cube3.position.set(25, 5.5, -12); scene.add(cube3);
方法二:缩放+位置调整组合
无需修改几何体,先创建基础高度的立方体,通过Y轴缩放实现目标高度,同时调整位置抵消向下偏移:
// 创建高度为1的基础立方体 const cubeGeometry2 = new THREE.BoxGeometry(10, 1, 5); const cubeMaterial2 = new THREE.MeshBasicMaterial({ color: '#5A5A5A', wireframe: false }); const cube3 = new THREE.Mesh(cubeGeometry2, cubeMaterial2); // 缩放Y轴到目标高度25 cube3.scale.y = 25; // 缩放后立方体中心在Y=12.5位置,调整位置让底部对齐原设定的Y=5.5 cube3.position.set(25, 5.5 + 12.5, -12); scene.add(cube3);
方法三:使用BufferGeometry(性能优先)
Three.js新版本推荐使用BufferGeometry,性能更优,修改顶点数据的方式如下:
const cubeGeometry2 = new THREE.BoxGeometry(10, 25, 5); // 转换为BufferGeometry const bufferGeo = new THREE.BufferGeometry().fromGeometry(cubeGeometry2); // 获取顶点位置数组 const positions = bufferGeo.attributes.position.array; // 遍历顶点,每个顶点的Y分量偏移12.5(原高度的一半) for (let i = 1; i < positions.length; i += 3) { positions[i] += 12.5; } // 标记位置属性已更新 bufferGeo.attributes.position.needsUpdate = true; const cubeMaterial2 = new THREE.MeshBasicMaterial({ color: '#5A5A5A', wireframe: false }); const cube3 = new THREE.Mesh(bufferGeo, cubeMaterial2); cube3.position.set(25, 5.5, -12); scene.add(cube3);
内容的提问来源于stack exchange,提问作者Mirza Viraad Baig
相关产品推荐
相关产品推荐

