Three.js r161中设置几何体位置后合并不生效的问题排查
问题:Three.js合并几何体前修改位置未生效
你用Three.js r161编写的代码如下:
import * as THREE from 'three'; import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, innerWidth / innerHeight, 0.1, 1000 ); camera.position.z = 10; // create material and 2 sphere: const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); const sphere_geo1 = new THREE.SphereGeometry( 2, 32, 32 ); // sphere_geo1.setAttribute('position', new THREE.BufferAttribute( new Float32Array([-5,0,0]), 3)); const sphere_geo2 = new THREE.SphereGeometry( 2, 32, 32 ); // merge spheres and add merged to scene: var merged_geo = BufferGeometryUtils.mergeGeometries([sphere_geo1, sphere_geo2], false); const merged = new THREE.Mesh( merged_geo, material ); scene.add(merged);
取消注释setAttribute那行代码后,第一个球体并未出现在x=-5的位置,这是因为你的操作逻辑有误。
错误原因
SphereGeometry生成的球体包含数千个顶点(32×32分段的球体约有3072个顶点),每个顶点都有独立的position坐标。你用setAttribute('position')直接覆盖整个位置缓冲区时,只传入了一个顶点的坐标[-5,0,0],这相当于把整个球体的所有顶点都替换成这一个点——球体直接变成了肉眼几乎不可见的点,自然无法看到它在目标位置。
正确解法
要移动整个几何体的位置,应该使用几何体的translate()方法,它会对所有顶点进行平移变换,从而整体移动几何体:
// 替换错误的setAttribute行,改用translate sphere_geo1.translate(-5, 0, 0);
修正后的完整代码
import * as THREE from 'three'; import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, innerWidth / innerHeight, 0.1, 1000 ); camera.position.z = 10; // create material and 2 sphere: const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); const sphere_geo1 = new THREE.SphereGeometry( 2, 32, 32 ); sphere_geo1.translate(-5, 0, 0); // 用translate平移几何体 const sphere_geo2 = new THREE.SphereGeometry( 2, 32, 32 ); // merge spheres and add merged to scene: var merged_geo = BufferGeometryUtils.mergeGeometries([sphere_geo1, sphere_geo2], false); const merged = new THREE.Mesh( merged_geo, material ); scene.add(merged); // 添加渲染循环确保画面正常显示 function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); } animate();
补充说明:如果不想修改几何体本身,也可以先创建两个Mesh,分别设置Mesh的position,再提取它们的几何体并应用Mesh的变换(mesh.geometry.applyMatrix4(mesh.matrix))后合并,但直接用几何体的translate方法是更简洁的方式。
内容的提问来源于stack exchange,提问作者Oto Shavadze
相关产品推荐
相关产品推荐

