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的使用,下一節說一說關於它的小應用。

 

轉載請註明地址:郭先生的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章