第八講 紋理映射
在前面幾講中,我們是通過Material節點來改變物體的外觀特性。這些特性僅僅是一致性的宏觀效果,對於物體的某些細節我們還沒有涉及到。通過紋理映射和處理可以為物體的表面細節增強表現力。本講分三個部分來討論:一是X3D基本紋理節點的使用,二是使用紋理的坐標系統,三是紋理的變換。
一、X3D基本紋理節點的使用
X3D中,提供了PixelTexture(像素紋理)、ImageTexture(貼圖紋理)和MovieTexture(影像紋理)三個節點。對於MovieTexture(影像紋理)節點,我們將在後面的"多媒體效果"中再做詳細討論,這裡僅討論前面兩個基本紋理節點。
1、PixelTexture(像素紋理)節點
PixelTexture 節點是用一個包含像素值的數組創建一個二維紋理帖圖,其主要屬性有:
image -- 用一個數組來定義一個二維圖像。該數組分為兩個部分,前三個是其特征值,後面的數值為實際的像素值。
前三個特征值的含義是:第一、二個數用來表示寬度方向和高度方向的像素個數,第三個值是表示後面實際像素字節的組成。具體如下:
當為1時,像素值為單字節,即取值范圍為0x00~0xFF,表示明亮程度(灰度);
當為2時,像素值為雙字節,第1個字節表示明亮程度,第2字節表示alpha值(即透明度)。
當為3時,像素值為三字節,分別用來表示RGB各顏色分量。
當為4時,像素值為四字節,前三個字節用來表示RGB各顏色分量,第四個字節表示alpha值。
repeatS -- 表示是否沿S軸水平重復紋理。默認值為True 。
repeatT -- 表示是否沿T軸垂直重復紋理。默認值為True 。
repeatT [repeatT: initializeOnly type SFBool (true|false) "true"]
下面來看一個簡單的示例代碼:
其中,PixelTexture 節點的image值為"2 2 3 0xff0000 0x00ff00 0x0000ff 0xffffff"。也就是說,像素值使用三字節,分別表示RGB各顏色分量。由於寬度和高度均指定2個數量,因此需要2×2=4個像素值。
結果如下圖所示,注意立方體的顏色分布(不同的浏覽器插件其結果可能不一樣)。
從上圖可以發現像素紋理處理的規律:默認時,自動將水平和垂直按指定寬度方向和高度方向的像素字節數進行平均分割,每一個分割區域的中點為像素紋理點,然後向四周進行過渡。參見下列示意圖:
若要指定透明度,可參照下列示例:
其中,PixelTexture 節點的image值為"2 2 4 0xff000000 0x00ff0040 0x0000ff80 0xffffffff"。結果如下圖所示:
上述代碼中,黃色球和像素紋理的立方體同在一個原點,由於設置了透明度,因此看起來很炫麗。你能看出alpha值的大小和透明度關系嗎?答案是:alpha值為0時完全透明,為0x00小0xff時不透明。
2、ImageTexture(貼圖紋理)節點
ImageTexture 是用來指定一個圖像映射到一個幾何形體的表面上。它與PixelTexture 節點的屬性基本相同,只不過image屬性被換成了url屬性。
ImageTexture節點的url屬性用來指定圖像的文件名和位置。例如下列代碼:
結果如下圖所示:
上述x3d.gif圖片文件是放在與示例代碼文件相同的文件夾中。需要說明的是:對於基本幾何體,默認處理時各個面均會貼圖。
二、使用紋理的坐標系統
我們知道,圖像和被映射的形體表面之間有一個映射關系。默認時,BS Contact是將圖像全部放大到對應的形體表面上。若改變此默認的映射比例,則可使用X3D的TextureCoordinate節點。
TextureCoordinate用來描述紋理帖圖自身所在的坐標點,該坐標點是二維的,分別表示對應圖像上的原點的相對水平和垂直距離。若坐標點取值在0到1之間,則這些坐標點落在圖像內部,否則落在圖像外部。
TextureCoordinate節點的坐標點屬性point通常用在IndexedFaceSet和ElevationGrid節點的texCoordindex屬性中。例如下面的代碼:
說明:
(1) IndexedFceset節點用來將一組頂點來構造的一個3D平面形體。各形體表面是在coordIndex屬性中通過來指定構造平面點(由Coordinate節點指定)的索引值來指定。當索引值為-1時,表明當前表面已經結束,下一個表面將要開始。
(2) 上述代碼中,IndexedFceset節點僅構造了一個面,如下面的示意圖所示,圖中的粗體數字表示該點在Coordinate節點的point屬性中的索引號。
注意:在計算機圖形學中,每一個面都有方向,並滿足右手定則:右手四指的方向是指定的點的次序方向,大拇指方向為該平面的法向方向。若構成立體的各個表面的法向方向都是從由立體內部指向外部,則圍成的是一個封閉的實體。
結果如下圖所示:
在上述代碼中再添加代碼,並修改IndexedFaceSet節點的texCoordindex屬性,如下所示:
結果如下:
分析:
(1) TextureCoordinate節點指定的坐標點如下所示的示意圖。由於在映射時,由IndexedFaceSet節點的texCoordindex屬性指定的平面多邊形圖像應和coordIndex屬性指定的平面多邊形相映射。即圖像0點和平面0點相對應,所以貼圖看起來是上圖的樣子。
(2) 若指定ImageTexture的repeatS和repeatT的屬性為True。則還會在面上沿水平方向和垂直方向重復貼圖。
上述代碼僅僅是構造一個面,若構造一個體也可同樣進行。如下面的代碼:
結果如下圖所示:
三、紋理的變換
X3D的節點TextureTransform 是用來改變帖圖的二維紋理坐標的位置、方向和比例, 因為帖圖先進行變換然後再貼到幾何體上,所以視覺效果是相反的。如下面的代碼:
結果如下圖所示:
注意:
(1) TextureTransform的值和顯示在形體上的結果剛好相反。
(2) 旋轉只要指定相應的旋轉角度(弧度值)即可。
(3) 坐標是圖像的相對坐標。即取值在0到1之間,則這些坐標點落在圖像內部,否則落在圖像外部。
(4) 水平和垂直方向的比例值可以不同。
需要說明的是:對於X3D的多重紋理的使用,由於BS插件支持的不是很好,故這裡暫不討論。在下一講中,我們將討論X3D場景的多媒體效果。