4

据我了解,您可以使用以下方法访问网格的每个顶点的 uv 坐标(“texels”):

geometry.faceVertexUvs[ materialIndex ][ faceIndex ][ vertexIndex ]

我正在苦苦挣扎的是,vertexIndex似乎遵循不同的映射顺序

geometry.vertices[ vertexIndex ]

我创建了一个示例来演示此问题:http ://andrewray.me/stuff/test-uv2.html

来源http ://andrewray.me/stuff/uv2.js

上面的代码执行以下操作:

  • 创建平面
  • 1使用效用dot函数在平面的索引顶点位置绘制一个球体:

    dot( floor.localToWorld( floor.geometry.vertices[1].clone() ) );

  • 修改 texelfaceVertexUvs[0][0][1]以便我们可以看到texel 在1哪里

    floor.geometry.faceVertexUvs[0][0][1].add( new THREE.Vector2( 0.4, 0 ) );

您可以在示例页面中看到,球体绘制在平面的右上角(顶点 1 的位置),而正在修改的纹素位于平面的左下角。顶点的索引不对齐!这是一个three.js错误,还是我错过了关于纹素的一些东西?

我发现顶点似乎像这样映射:

texel index | vertex index
0           | 3
1           | 1
2           | 0
3           | 2

但是,在尝试完成相关的 uv 映射任务时,我看到了一些其他意外行为,所以我不知道映射是否是我的错误的根源。

4

1 回答 1

4

我不知道是否有更好的方法,但映射似乎是这样工作的:

geometry.faceVertexUvs[ 0 ][ faceIndex ][ vertexIndex ]

vertexIndex对应于face的顶点索引,而不是几何顶点数组。虽然显示为 0-3 的数字(对于四边形),但实际面将值定义为 ad(来自Face4 文档):

Face4( a, b, c, d ... )

> geometry.faces[0] // assuming faceIndex is 0
THREE.Face4 {a: 0, b: 2, c: 3, d: 1, normal: THREE.Vector3…}

看,这是我们的映射!

因此,要在它们之间进行映射,我们需要在该索引处找到人脸,并将 0 映射到 a、1 到 b 等,然后在 geometry.vertices 数组中查找。这是一种愚蠢但实用的方法:

geometry.vertices[
    geometry.faces[faceIndex][ String.fromCharCode(97 + vertexIndex) ]
];

其中 vertexIndex 是由faceVertexUvs[0][faceIndex][vertexIndex]. fromCharCode映射a0等等。现在我们有了每个 uv 纹素的顶点(和它的位置)!呜呜!

于 2013-06-26T07:11:50.197 回答