我目前正在尝试创建一个具有大量面孔(数千个)并使用纹理的three.js网格物体。但是,我的问题是每个面都可以在运行时更改其纹理,因此可能每个面都有不同的纹理。
我尝试使用默认纹理预加载材质数组(对于MeshFaceMaterial)并为每个面分配不同的materialIndex,但这会产生很多延迟。
一些研究导致here,其中说
如果数字很大(例如每张脸可能有所不同),请考虑不同的解决方案,使用属性/纹理来驱动不同的每个脸部外观。
我对着色器的工作原理有点困惑,特别是我甚至不确定如何使用带有属性的纹理。我在网上找不到任何这样的例子,因为我发现大多数纹理着色器相关的例子都使用了制服。
所以我的问题是:是否有一种有效的方法来创建具有大量纹理的网格,在运行时可以更改?如果没有,是否有上述属性/纹理想法的例子?
答案 0 :(得分:1)
实际上,这可能是一件棘手的事情。现在我不能说很多GLSL(我正在学习),但我所知道的是制服是常量而且不会在通话之间改变,所以你可能想要一个属性用于你的情况,但我欢迎在这里错。但是,我确实有一个更简单的建议。
您可以使用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,但我不知道你的用例。对于completness,您需要在运行时运行mesh.geometry.uvsNeedUpdate = true;
以查看更新。我希望有所帮助。