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的使用,下一节说一说关于它的小应用。
转载请注明地址:郭先生的博客