Three.js:为BufferGeometry设置setIndex / indices的正确方法?

我正在尝试在BufferGeometry中设置每面UV指数.

我从几何学开始.我的几何体的每个面都有一个对应于UV索引的face.materialIndex.我正在尝试将其转换为BufferGeometry,然后将face.materialIndex映射到BufferGeometry.

这是我到目前为止所拥有的:

// Convert geometry > buffergeometry
const bufGeo = new BufferGeometry().fromGeometry( geometry );

// Get an array of all the original geometry's indices...
const faceIndices = geometry.faces.map( face => face.materialIndex );

// Build a new array with the indices...
const indices = new Uint16Array( faceIndices );

// Apply to the BufferGeometry
bufGeo.setIndex( new BufferAttribute( indices, 1 ) );

现在,这似乎破坏了我的网格,使其根本不绘制.我究竟做错了什么?

顺便说一下,当Geometry转换为BufferGeometry时,Three.js将其置于中间格式,首先称为DirectGeometry.这用于复制索引,但是it was removed for reasons unknown in this commit by Mr Doob.现在三个似乎完全丢弃指数Geo> BufGeo转换.

我也尝试使用该提交中的代码(修改为使用setIndex):

const indices = new Uint16Array( faceIndices.length * 3 );
bufGeo.addAttribute( 'index', new BufferAttribute( indices, 1 ).copyIndicesArray( faceIndices ) );

但我有同样的问题.生成的网格被破坏了.

最佳答案 setIndex函数用于指定引用BufferGeometry上的顶点属性缓冲区的三角形索引.在您的示例中,您将三角形索引数组设置为从每个面的materialIndex生成的数组.

materialIndex对应于从材质数组渲染该三角形的材质,而不是UV索引.从Face3 documentation

materialIndex — (optional) which index of an array of materials to associate with the face.

除非你做了改变它的事情,否则每个面的materialIndex很可能为零,这可以解释为什么你的模型停止绘制(面上的顶点都是相同的).

这行是你的问题:

//获取所有原始几何体索引的数组……
const faceIndices = geometry.faces.map(face => face.materialIndex);

值得注意的是,通过这种方式生成数组,您将获得属性所需数量的1/3,因为每个面有3个顶点.

可能的解决方案

>如果你想用不同的材料渲染每个面,就像materialIndex对应的那样,那么我会看一下groups for BufferGeometry
>如果你想为BufferGeometry实际生成自定义UV坐标,我会查看BufferAttributesBufferGeometry.addAttribute函数来添加新的UV属性.

希望有所帮助!

点赞