three.js UV映射简述

今天郭先生来说一说uv映射,什么是uv映射?uv映射就是将二维的贴图映射到对象的一个面(或者多个面)上。说到这个问题,我们就不得不了解一下Geometry的点、面和uv的结构。我们以BoxGeometry为例。

new THREE.BoxGeometry(20, 20, 20); //创建一个边长为20的正方体。

我们可以发现一个长方体由八个点和12个三角面组成,就拿0-1-2-3这个面来看,两个面的face3分别是:

也就是faces[0]对应顶点0-2-1,faces[1]对应顶点2-3-1,这个顺序可以记一下。
Face3里面有一个很重要的属性materialIndex,这个索引是当使用数组材质的时候指定使用哪个材质作为当前Face3的材质,对于BoxGeometry来说,前面的两个三角面的materialIndex为0,后面的两个为1,上面两个为2,下面的两个为3,左面两个为4,右面的两个为5,即使数组中只有两个材质,那么也是按照这个顺序(既只显示前后两个面)。

再说说uv映射,一个纹理图的原点在其左下方,坐标为(0,0),右下方为(1,0),左上方为(0,1),右上方为(1,1)

在Geometry中,faceVertexUvs决定了uv映射的关系,如下如就是uv映射关系

我们可以看出第一个三角面对应一个二维点数组[new THREE.Vector2(0,1), new THREE.Vector2(0,0), new THREE.Vector2(1, 1)],他默认将face3[0]的第一个点对应纹理的第一个点,face3[0]的第二个点对应纹理的第二个点,,face3[0]的第三个点对应纹理的第三个点,最后的到的如下图,

 

我们稍微改变一下[new THREE.Vector2(0.25,0.75), new THREE.Vector2(0.25,0.25), new THREE.Vector2(0.75, 0.75)],看看会发生什么,

就变成这个样子了,原因看下图

接下来我们以数组材质的方式和单张纹理图的方式说一下如何将6个面赋予不同的贴图(默认六个面是相同的贴图)。

1. 数组材质的方式

这种方法十分简单,只需要创建6个贴图材质即可

var geom = new THREE.BoxGeometry(20, 20, 20);
var mate1 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/kaola.png')});
var mate2 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/mao.png')});
var mate3 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/quan.png')});
var mate4 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/shi.png')});
var mate5 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/tuboshu.png')});
var mate6 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/xiongmao.png')});

var mesh = new THREE.Mesh(geom, [mate1, mate2, mate3, mate4, mate5, mate6]);
scene.add(mesh);

2. 单张纹理图

如下图所示,将六个面的纹理贴图绘制到一张

var geom = new THREE.BoxGeometry(20, 20, 20);
var mate = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/an-uv.png')});
var mesh = new THREE.Mesh(geom, mate);
geom.faceVertexUvs[0][0] = [new THREE.Vector2(0,1), new THREE.Vector2(0,0.66), new THREE.Vector2(0.5, 1)];
geom.faceVertexUvs[0][1] = [new THREE.Vector2(0,0.66), new THREE.Vector2(0.5,0.66), new THREE.Vector2(0.5, 1)];
geom.faceVertexUvs[0][2] = [new THREE.Vector2(0.5,1), new THREE.Vector2(0.5,0.66), new THREE.Vector2(1, 1)];
geom.faceVertexUvs[0][3] = [new THREE.Vector2(0.5,0.66), new THREE.Vector2(1,0.66), new THREE.Vector2(1, 1)];
geom.faceVertexUvs[0][4] = [new THREE.Vector2(0,0.66), new THREE.Vector2(0,0.33), new THREE.Vector2(0.5, 0.66)];
geom.faceVertexUvs[0][5] = [new THREE.Vector2(0,0.33), new THREE.Vector2(0.5,0.33), new THREE.Vector2(0.5, 0.66)];
geom.faceVertexUvs[0][6] = [new THREE.Vector2(0.5,0.66), new THREE.Vector2(0.5,0.33), new THREE.Vector2(1, 0.66)];
geom.faceVertexUvs[0][7] = [new THREE.Vector2(0.5,0.33), new THREE.Vector2(1,0.33), new THREE.Vector2(1, 0.66)];
geom.faceVertexUvs[0][8] = [new THREE.Vector2(0,0.33), new THREE.Vector2(0,0), new THREE.Vector2(0.5, 0.33)];
geom.faceVertexUvs[0][9] = [new THREE.Vector2(0,0), new THREE.Vector2(0.5,0), new THREE.Vector2(0.5, 0.33)];
geom.faceVertexUvs[0][10] = [new THREE.Vector2(0.5,0.33), new THREE.Vector2(0.5,0), new THREE.Vector2(1, 0.33)];
geom.faceVertexUvs[0][11] = [new THREE.Vector2(0.5,0), new THREE.Vector2(1,0), new THREE.Vector2(1, 0.33)];

scene.add(mesh);

他们的结果同下图。这里faceVertexUvs数组的第一维度是材质的索引,第二维度才是面的uv贴图映射关系,由于只有一个材质,所以这里的索引都是0。

这节说了一下uv的使用,下一节说一说关于它的小应用。

 

转载请注明地址:郭先生的博客

posted @ 2020-08-17 13:59  郭先生的博客  阅读(6145)  评论(1编辑  收藏  举报