THREE.js中单个网格的多个UV /纹理

The*_*ion 5 javascript 3d textures uv-mapping three.js

我有一个使用四个纹理的OBJ。文件中定义的UV的范围是(0,0)到(2,2),这样(0.5,0.5)表示第一纹理中的坐标,(0.5,1.5)是第二纹理中的UV坐标, (1.5,0.5)是第三个纹理中的坐标,而(1.5,1.5)是最后一个纹理中的坐标。

我已经有了正确的three.js几何图形或对象。但是,我现在需要能够将正确的纹理贴图应用于这些对象。

在代码中:

我有一个THREE.Mesh正确的几何图形(UV坐标为U = [0,2],V = [0,2])和虚拟占位符材料。我目前加载单个纹理,如下所示:

var texture = new THREE.TextureLoader().load('tex_u1_v1.png', function() {
    object.material.map = texture;
    object.material.map.needsUpdate = true;
});
Run Code Online (Sandbox Code Playgroud)

如预期的那样,四分之一的网格已正确纹理化。我有三个比较有质感文件tex_u1_v2.pngtex_u2_v1.pngtex_u2_v2.png。我希望能够将这些纹理也应用到object(THREE.js网格),这样网格中的每个有效UV都有一个纹理。

但是,我不知道object在创建之后如何向其中添加多种材料。而且,我不知道如何指定网格tex_u1_v2.png,例如,应将其用于范围为(U = [0,2],V = [1,2])的UV。

Jav*_*ave 6

Three 中的标准材质只接受一个纹理对象来处理各种贴图参数(并且纹理对象只包含一个图像),所以为了在你的对象上使用多个纹理,你必须使用多个材质创建你自己的多纹理材料。如果您有着色器编程的经验,那么使用后一种方法可能会获得最佳性能(假设您有足够的视频内存用于大型纹理),因为您可以在一次绘制调用中绘制整个网格,而无需加载新的着色器或纹理。

要创建您自己的着色器,您可以使用ShaderMaterialor RawShaderMaterial,为您需要的每个纹理(在您的情况下为四个)提供一个统一的纹理,然后在着色器代码中根据坐标选择正确的一个进行采样。

要使对象使用多个材质,您可以将material属性设置为一组材质(在创建期间使用构造函数参数,或者在稍后阶段手动替换它)。

const myMaterials = [tex1Material, tex2Material, tex3Material, tex4Material];
const myMesh = new THREE.Mesh(myGeometry, myMaterials);
//Or:
myMesh.materials = myMaterials;
Run Code Online (Sandbox Code Playgroud)

然后,要使网格的不同部分使用适当的材料,groups如果它是BufferGeometry; 或者materialIndex如果您使用的是Geometry. 材质索引(在组和面中)是mesh.material上面显示的数组中材质的索引。

既然网格的不同部分具有不同的材质,您就可以为每种材质赋予自己的纹理。

  • 获取纹理正确 uv 坐标的最简单方法可能是将每个部分保持在 [0,1] 区间内。由于网格的每个部分都使用独特的材料,因此您不必担心坐标重叠。

如果您不想修改已经存在的坐标,则有两种替代方法:

这是演示这些方法的 jsfiddle 的链接:https ://jsfiddle.net/xfehvmb4/