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