1

我目前正在尝试创建一个 three.js 网格,它有大量的面(数千个)并且正在使用纹理。但是,我的问题是每个面都可以在运行时更改其纹理,因此每个面都有可能具有不同的纹理。

我尝试使用默认纹理预加载材质数组(用于 MeshFaceMaterial)并为每个面分配不同的材质索引,但这会产生很大的延迟。

一些研究导致这里

如果数量很大(例如每张脸可能不同),请考虑不同的解决方案,使用属性/纹理来驱动不同的每张脸外观。

我对着色器的工作方式有点困惑,尤其是我什至不确定如何使用带有属性的纹理。我在网上找不到任何这样的例子,因为我发现大多数与纹理着色器相关的例子都使用制服。

所以我的问题是:是否有一种有效的方法来创建具有大量纹理且在运行时可更改的网格?如果没有,是否有上述属性/纹理想法的示例?

4

1 回答 1

1

事实上,这可能是一件很难实现的事情。现在我不能对 GLSL 说太多(我正在学习),但我所知道的是 Uniforms 是常量,不会在调用之间改变,所以你可能需要一个属性来适应你的情况,但我欢迎在这里犯错。但是,我确实有一个更简单的建议。

您可以使用 1 个纹理,您可以将其“细分”为每个面所需的所有微小纹理。然后在运行时,您可以从纹理中提取 UV 坐标并将其单独应用于面。您仍然需要处理计算时间,但是对于一千个左右的面,它应该是可行的。我用一个 25k 的人脸模型进行了测试,它每次都可以快速改变所有的人脸。

现在的诀窍是导航 faceVertexUvs 3 维数组。但是例如一个有 12 个面的纹理立方体,你可以说将所有面重置为等于一侧,如下所示:

for (var uvCnt = 0; uvCnt < mesh.geometry.faceVertexUvs[0].length; uvCnt+=2 ) {
    mesh.geometry.faceVertexUvs[0][uvCnt][0] = mesh.geometry.faceVertexUvs[0][2][0];
    mesh.geometry.faceVertexUvs[0][uvCnt][1] = mesh.geometry.faceVertexUvs[0][2][1];
    mesh.geometry.faceVertexUvs[0][uvCnt][2] = mesh.geometry.faceVertexUvs[0][2][2];

    mesh.geometry.faceVertexUvs[0][uvCnt+1][0] = mesh.geometry.faceVertexUvs[0][3][0];
    mesh.geometry.faceVertexUvs[0][uvCnt+1][1] = mesh.geometry.faceVertexUvs[0][3][1];
    mesh.geometry.faceVertexUvs[0][uvCnt+1][2] = mesh.geometry.faceVertexUvs[0][3][2];
}

在这里,我有一个有 6 种颜色(每边 1 种)的立方体,我循环遍历每个 faceVertexUv(步长为 2,因为两个三角形组成一个平面)并将所有 Uv 重置为我的第二面,即蓝色。当然,您需要将坐标映射到各种对象中,以便您可以轻松地查询对象以返回并重置相应的 Uv,但我不知道您的用例。为了完整起见,您需要在运行mesh.geometry.uvsNeedUpdate = true;时运行以查看更新。我希望这会有所帮助。

于 2013-10-06T15:14:37.657 回答