Three.js:为 BufferGeometry 设置索引/索引的正确方法? [英] Three.js: Correct way to setIndex / indices for BufferGeometry?

查看:105
本文介绍了Three.js:为 BufferGeometry 设置索引/索引的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 BufferGeometry 中设置每面 UV 索引.

I'm trying to set per-face UV indices in a BufferGeometry.

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

I'm starting with a Geometry. Each face of my geometry has a face.materialIndex corresponding to a UV index. I'm trying to convert this to a BufferGeometry, and then map over the face.materialIndex to the 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 ) );

现在这似乎破坏了我的网格并使其根本无法绘制.我做错了什么?

Right now this appears to clobber my mesh and make it not draw at all. What am I doing wrong?

顺便说一下,在后台,当 Geometry 转换为 BufferGeometry 时,Three.js 将其置于首先称为 DirectGeometry 的中间格式中.这曾经用于复制索引,但是

By the way, under the hood, when a Geometry is converted to a BufferGeometry, Three.js puts it in an intermediary format first called a DirectGeometry. This used to copy over indices, but it was removed for reasons unknown in this commit by Mr Doob. Right now Three appears to discard indices entirely in a Geo > BufGeo conversion.

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

I have also tried using the code from that commit (modified to use setIndex):

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

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

But I have the same problem. The resulting mesh is clobbered.

推荐答案

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

The setIndex function is used to specify triangle indices that reference the vertex attribute buffers on the BufferGeometry. In your example you're setting the the triangle index array to an array generated from the materialIndex of each face.

materialIndex 对应于从一系列材料中渲染该三角形的材料,而不是 UV 索引.来自 Face3 文档:

The materialIndex corresponds to a material to render that triangle with from an array of materials, not a UV index. From the Face3 documentation:

materialIndex —(可选)与面关联的材料数组的索引.

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

很可能每个面的 materialIndex 都为零,除非您已对其进行了更改,这将解释为什么您的模型停止绘制(面上的顶点都是相同的)).

It's very possible that that materialIndex is zero for every face unless you've done something to change it, which would explain why your model stops drawing (the vertices on the faces are all the same one).

这一行是你的问题:

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

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

It might also be important to note that you'll be getting 1/3 as many array elements as you need for an attribute by generating an array this way, because there are 3 vertices per face.

可能的解决方案

  • 如果你想用不同的材质渲染每个面,就像 materialIndex 对应的那样,那么我会看看 BufferGeometry 的组

  • If you're looking to render each face with a different material, as the materialIndex corresponds to, then I would look into groups for BufferGeometry

如果您想为 BufferGeometry 实际生成自定义 UV 坐标,我会查看 BufferAttributesBufferGeometry.addAttribute 函数添加新的 UV 属性.

If you want to actually generate custom UV coordinates for a BufferGeometry, I would look into BufferAttributes and the BufferGeometry.addAttribute function to add the new UV attribute.

希望有帮助!

这篇关于Three.js:为 BufferGeometry 设置索引/索引的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆