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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 15:45:20