今天郭先生來說一說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的使用,下一節說一說關於它的小應用。
轉載請註明地址:郭先生的部落格