Three.js:平滑未索引BufferGeometry上的法线



我正试图从未索引的BufferGeometry开始平滑网格的法线。这个问题以前已经回答过了,但是Three.js api从那以后发生了很大的变化,我无法让它在r130 上工作

据我所知,我需要首先合并顶点以获得索引的BufferGeometry,然后重新计算法线,但这似乎不起作用。

下面是一个使用defaulf立方体的最小示例:

// Scene
const scene = new THREE.Scene();

// Geometry
const boxGeometry = new THREE.BoxGeometry(.7,.7,.7);

// Materials
const shadedMaterial = new THREE.MeshStandardMaterial();
shadedMaterial.metalness = 0.4;
shadedMaterial.roughness = 0.4;
shadedMaterial.color = new THREE.Color(0xffffff);

// Mesh
const smoothBoxGeometry=BufferGeometryUtils
.mergeVertices(new THREE.BufferGeometry().copy(boxGeometry))
smoothBoxGeometry.computeVertexNormals();
smoothBoxGeometry.computeBoundingBox();
smoothBoxGeometry.normalizeNormals();

const box = new THREE.Mesh(smoothBoxGeometry, shadedMaterial);
scene.add(box);

平面阴影立方体而不是预期的平滑阴影立方体

我错过了什么?

这样试试:

let camera, scene, renderer;
let mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 4;
scene = new THREE.Scene();
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 20, 0);
scene.add(hemiLight);
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(-3, 10, -10);
scene.add(dirLight);
let geometry = new THREE.BoxGeometry();
geometry.deleteAttribute('normal');
geometry.deleteAttribute('uv');
geometry = THREE.BufferGeometryUtils.mergeVertices(geometry);
geometry.computeVertexNormals();
const material = new THREE.MeshStandardMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.130.1/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.130.1/examples/js/utils/BufferGeometryUtils.js"></script>

BufferGeometryUtils.mergeVertices()只能在顶点数据相同的情况下执行合并。为了确保这一点,有必要删除现有的法线和uv属性。