1.什麼是UV? android
對於三維模型,有兩個最重要的座標系統,一是頂點的位置(X,Y,Z)座標,另外一個就是UV座標。什麼是UV?簡單的說,就是貼圖影射到模型表面的依據。 完整的說,其實應該是UVW(由於XYZ已經用過了,因此另選三個字母表示)。U和V分別是圖片在顯示器水平、垂直方向上的座標,取值通常都是0~1,也 就是(水平方向的第U個像素/圖片寬度,垂直方向的第V個像素/圖片高度)。那W呢?貼圖是二維的,何來三個座標?嗯嗯,W的方向垂直於顯示器表面,通常 用於程序貼圖或者某些3D貼圖技術(記住,確實有三維貼圖這種概念!),對於遊戲而言不經常使用到,因此通常咱們就簡稱UV了。數組
全部的圖象文件都是二維的一個平面。水平方向是U,垂直方向是V,經過這個平面的,二維的UV座標系。咱們能夠定位圖象上的任意一個象素。可是一個問題是如何把這個二維的平面貼到三維的NURBS表面和多邊形表面呢? 對於NURBS表面。因爲他自己具備UV參數,儘管這個UV值是用來定位表面上的點的參數,但因爲它也是二維的,因此很容易經過換算把表面上的點和平面圖象上的象素對應起來。因此把圖象貼帶NURBS是很直接的一件事。可是對於多變形模型來說,貼圖就變成一件麻煩的事了。因此多邊形爲了貼圖就額外引進了一個UV座標,以便把多邊形的頂點和圖象文件上的象素對應起來,這樣才能在多邊形表面上定位紋理貼圖。因此說多邊形的頂點除了具備三維的空間座標外。還具備二維的UV座標。 函數
UV" 這裏是指u,v紋理貼圖座標的簡稱(它和空間模型的X, Y, Z軸是相似的). 它定義了圖片上每一個點的位置的信息. 這些點與3D模型是相互聯繫的, 以決定表面紋理貼圖的位置. UV就是將圖像上每個點精確對應到模型物體的表面. 在點與點之間的間隙位置由軟件進行圖像光滑插值處理. 這就是所謂的UV貼圖.
那爲何用UV座標而不是標準的投影座標呢? 一般給物體紋理貼圖最標準的方法就是以planar(平面),cylindrical(圓柱), spherical(球形),cubic(方盒)座標方式投影貼圖.
Planar projection(平面投影方式)是將圖像沿x,y或z軸直接投影到物體. 這種方法使用於紙張, 佈告, 書的封面等 - 也就是表面平整的物體.平面投影的缺點是若是表面不平整, 或者物體邊緣彎曲, 就會產生如圖A的不理想接縫和變形. 避免這種狀況須要建立帶有alpha通道的圖像, 來掩蓋臨近的平面投影接縫, 而這會是很是煩瑣的工做. 因此不要對有較大厚度的物體和不平整的表面運用平面投影方式. 對於立方體能夠在x, y方向分別進行平面投影, 可是要注意邊緣接縫的融合. 或者採用無縫連續的紋理, 並使用cubic投影方式. 多數軟件有圖片自動縮放功能, 使圖像與表面吻合. 顯然, 若是你的圖像與表面形狀不一樣, 自動縮放就會改變圖像的比例以吻合表面. 這一般會產生不理想的效果, 因此製做貼圖前先測量你的物體尺寸.工具
二、uv紋理座標設定與貼圖規則 性能
當opengl對一個四方形進行貼圖時,會定義紋理貼圖座標,一串數組,相信初學openggl es者看到後會很頭疼,不知道寫得是什麼東西。如今就將個人研究成果與你們分享下!spa
當紋理映射啓動後繪圖時,你必須爲OpenGL ES提供其餘數據,即頂點數組中各頂點的紋理座標。紋理座標定義了圖像的哪一部分將被映射到多邊形。它的工做方式有點奇怪。 遊戲
下面看下在android平臺下Opengl紋理系統座標,左下角爲原點。圖片
咱們如今討論怎樣使用這些紋理座標。當咱們指定頂點數組中的頂點時,咱們須要在另外一個數組中提供紋理座標,它稱爲紋理座標數組。這裏須要注意定義座標數組順序,這很關鍵。資源
float texCoords[] = new float[] {
// FRONT
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
};io
效果以下:
若是咱們想截取圖片有上角不分作紋理,按照上面方法可獲的數組
float texCoords[] = new float[] {
// FRONT
0.5f, 0.5f,
1f, 0.5f,
0.5f, 1f,
1f, 1f
};
效果以下:
咱們看下貼圖的原始文件
你會發現截屏中的圖片y軸是顛倒的,其實這是android圖像座標系統與Opengl es 座標系統不一致致使的。最簡單的修正辦法將原始圖片用工具翻轉過來,這樣會比用程序翻轉節省不少性能,資源是寶貴的。
三角形紋理映射,只要按照咱們的映射規則,即可以順利完成映射。
float texCoords[] = new float[] {
0.0f, 0.0f,
1.0f, 0.0f,
0.5f, 1.0f,
};
效果:
看到這裏應該知道紋理座標數組規則定義的意義了吧。
平鋪與箔拉
咱們的紋理座標系統在兩個軸上都是從0.0 到 1.0,若是設置超出此範圍的值會怎麼樣?根據視圖的設置方式有兩種選擇。
平鋪(也叫重複)
一種選擇是平鋪紋理。按OpenGL的術語,也叫「重複」。若是咱們將第一個紋理座標數組的全部1.0改成2.0:
static const GLfloat texCoords[] = {
0.0, 2.0,
2.0, 2.0,
0.0, 0.0,
2.0, 0.0
};
咱們能夠經過glTexParameteri()函數設置。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
箝位
另外一種可能的選擇是讓OpenGL ES簡單地將超過1.0的值限制爲1.0,任何低於0.0的值限制爲 0.0。這實際會引發邊沿像素重複。
咱們能夠經過glTexParameteri()函數設置。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);