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.png
,tex_u2_v1.png
和tex_u2_v2.png
。我希望能够将这些纹理也应用到object
(THREE.js网格),这样网格中的每个有效UV都有一个纹理。
但是,我不知道object
在创建之后如何向其中添加多种材料。而且,我不知道如何指定网格tex_u1_v2.png
,例如,应将其用于范围为(U = [0,2],V = [1,2])的UV。
Three 中的标准材质只接受一个纹理对象来处理各种贴图参数(并且纹理对象只包含一个图像),所以为了在你的对象上使用多个纹理,你必须使用多个材质或创建你自己的多纹理材料。如果您有着色器编程的经验,那么使用后一种方法可能会获得最佳性能(假设您有足够的视频内存用于大型纹理),因为您可以在一次绘制调用中绘制整个网格,而无需加载新的着色器或纹理。
要创建您自己的着色器,您可以使用ShaderMaterial
or 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
上面显示的数组中材质的索引。
既然网格的不同部分具有不同的材质,您就可以为每种材质赋予自己的纹理。
如果您不想修改已经存在的坐标,则有两种替代方法:
将纹理环绕设置为THREE.RepeatWrapping
:
myTexture.wrapS = THREE.RepeatWrapping;
myTexture.wrapT = THREE.RepeatWrapping;
Run Code Online (Sandbox Code Playgroud)
这将使纹理重复超出标准 [0-1] uv 间隔。
另一种方法是使用offset
纹理的属性将其推回到 [0-1] 区间。对于要放置在 u[0,1], v[1,2] 间隔中的纹理,您可以将 v 坐标的偏移量设置为 -1:
myTexture.offset = new THREE.Vector2(0, -1);
Run Code Online (Sandbox Code Playgroud)这是演示这些方法的 jsfiddle 的链接:https ://jsfiddle.net/xfehvmb4/
归档时间: |
|
查看次数: |
1544 次 |
最近记录: |