王浩杰
(四川大學(xué)計(jì)算機(jī)學(xué)院,成都610065)
紋理映射(Texture Mapping)是計(jì)算機(jī)圖形學(xué)中常用的一種技術(shù),它被廣泛應(yīng)用在3D游戲開(kāi)發(fā),虛擬現(xiàn)實(shí)(Virtual Reality),三維真實(shí)感圖形的生成和顯示等領(lǐng)域中。各種各樣復(fù)雜圖形的渲染中也使用了紋理映射技術(shù)[1]??梢詫⒓y理映射定義為:將紋理空間中的紋理圖像映射到物體表面的過(guò)程。傳統(tǒng)的紋理映射算法,大多數(shù)是基于平面的,很多工業(yè)造型物體表面比如汽車、飛機(jī)、花瓶等,都是由自由曲面或不規(guī)則多邊形構(gòu)成,這些物體的難以用參數(shù)表達(dá)式直接表示,因此也不能直接進(jìn)行紋理映射,這也是紋理映射中的難題之一。針對(duì)這些難點(diǎn),本文主要對(duì)參數(shù)曲面和不規(guī)則曲面之間的紋理映射算法進(jìn)行研究。
映射(Mapping)是紋理映射中的核心問(wèn)題,兩個(gè)集合中元素中間的對(duì)應(yīng)關(guān)系可以用映射來(lái)表示。而紋理映射可以認(rèn)為是建立兩個(gè)集合之間的映射關(guān)系。紋理空間用紋理圖像的定義域空間表示,景物空間就是需要映射的三維物體表面。紋理映射中主要包含兩個(gè)映射[2]:
假設(shè)點(diǎn)P1(x,y)是紋理圖像上任一點(diǎn)的坐標(biāo),是三維景物表面上任一點(diǎn)的坐標(biāo),紋理圖像到景物空間的映射就是確定三維景物表面上的點(diǎn)和紋理圖像上的點(diǎn)之間的對(duì)應(yīng)關(guān)系[3],然后將紋理值賦給景物空間點(diǎn),映射可以用下式表示:
景物空間到屏幕空間的映射:將景物變換為目標(biāo)圖像,通過(guò)取景變換將景物顯示到屏幕上,即可得到最終的計(jì)算機(jī)圖像。
根據(jù)紋理圖像和景物空間之間的映射順序,紋理映射可以分為:正向映射、逆向映射和兩步法紋理映射。
參數(shù)曲面紋理映射最開(kāi)始采用的就是正向映射[4]的算法,也可以把它稱為紋理掃描法(Texture Scan?ning)。參數(shù)曲面紋理映射關(guān)鍵是求出目標(biāo)參數(shù)曲面的逆映射,但是一般參數(shù)曲面的逆映射難以確定,最開(kāi)始采用的是一種遞歸分割的方法[5],近似地建立了離散的映射關(guān)系,將紋理坐標(biāo)和參數(shù)曲面坐標(biāo)進(jìn)行一一映射,確定紋理像素在景物參數(shù)曲面的位置和大小,再通過(guò)線性插值計(jì)算參數(shù)曲面上對(duì)應(yīng)點(diǎn)的像素中心處的參數(shù)值。正向映射的優(yōu)點(diǎn)是實(shí)現(xiàn)相對(duì)簡(jiǎn)單,缺點(diǎn)是映射過(guò)程中景物參數(shù)空間和紋理空間不能完全對(duì)應(yīng)。正向映射過(guò)程如圖1所示。
圖1 正向映射
逆向映射技術(shù)是Blinn[6]提出來(lái)的,逆向映射是一個(gè)和正向映射相反的過(guò)程,逆向映射也成被稱為屏幕掃描法(Screen Scanning)[7]。在逆向映射中,先將圖像空間中像素I所表示的區(qū)域投影到景物空間區(qū)域S,然后將S區(qū)域映射到紋理空間;這里需要對(duì)紋理圖像進(jìn)行重采樣,計(jì)算曲面空間坐標(biāo)中心的像素值,然后將計(jì)算結(jié)果賦值給曲面空間。逆向映射算法在一定程度上改進(jìn)了正向映射的缺點(diǎn),實(shí)現(xiàn)了紋理空間和景物參數(shù)空間的完全對(duì)應(yīng)。逆向映射也是紋理映射中應(yīng)用較普遍的方法之一。
對(duì)于一些復(fù)雜的物體,其曲面一般是非線性的,難以直接參數(shù)化,不能直接對(duì)其使用紋理映射,但是可以借助兩步法紋理映射技術(shù)[8]。其核心思想就是把原來(lái)的映射拆分為兩個(gè)映射,這個(gè)過(guò)程需要借助一個(gè)中間曲面來(lái)實(shí)現(xiàn),把紋理圖像映射到簡(jiǎn)單的中間曲面的映射記為S映射,中間曲面到最終的景物表面的映射記為O映射[9]。用O映射和S映射的復(fù)合表示完整的映射,兩步法紋理映射可以分為下面的兩個(gè)步驟:
選定一個(gè)合適的中間曲面是兩步法紋理映射的關(guān)鍵,一般來(lái)說(shuō),常見(jiàn)的中間曲面有球面、立方體表面、圓柱面和自由曲面,要想得到的一個(gè)比較好的紋理映射效果,選定的中間曲面需要貼近最終的目標(biāo)曲面。選定中間曲面后,然后建立中間曲面到景物表面的映射關(guān)系。
先介紹簡(jiǎn)單的二次曲面的紋理映射。如果可以通過(guò)一些變換把紋理空間轉(zhuǎn)換到參數(shù)空間,一些簡(jiǎn)單二次曲面的逆映射表達(dá)式,可以直接進(jìn)行紋理映射[10]。但是對(duì)于復(fù)雜的高次參數(shù)曲面來(lái)說(shuō),參數(shù)曲面的逆映射求不出解析表達(dá)式,只能通過(guò)一些數(shù)值求解算法來(lái)離散求解它們的逆映射。簡(jiǎn)單的二次曲面,其紋理映射逆映射可以用它的解析表達(dá)式表示。
以圓柱面為中間曲面的參數(shù)表示,一個(gè)高為h,半徑為r的圓柱面的參數(shù)表達(dá)式為:
以圓柱面為中間曲面的紋理映射的原理如圖2所示:
圖2 柱面映射
常用的自由曲面有Bezier曲面[11]和B樣條曲面,它們可以靈活的控制曲面的形狀?;诳刂泣c(diǎn)實(shí)現(xiàn)的自由曲面控制靈活,方便造型,易于拼接。參數(shù)曲面的解析表達(dá)式就是二維參數(shù)空間到三維空間的映射,利用其解析表達(dá)式能夠方便實(shí)現(xiàn)紋理映射。
Bezier曲面的定義如下:設(shè)Pij(i=0,1,…,m;j=0,1,…,n)為( )m+1×(n+1)個(gè)控制點(diǎn)列,則m×n次Bezier曲面定義為:
其中Pij是控制點(diǎn),是Bernstein基函數(shù)。當(dāng)n=m=3時(shí),得到的雙三次Bezier曲面如下:
矩陣形式如下:
Pij(i=0,1,2,3;j=0,1,2,3)構(gòu)成了參數(shù)曲面的控制點(diǎn)矩陣,一張雙三次Bezier曲面片由16個(gè)控制點(diǎn)確定。由Pij組成的空間網(wǎng)格稱為特征網(wǎng)格,曲面的形狀受到特征網(wǎng)格中控制頂點(diǎn)的控制,通過(guò)調(diào)節(jié)控制頂點(diǎn),曲面的形狀也隨之改變。雙三次Bezier曲面如圖3所示:
圖3 雙三次Bezier曲面
在計(jì)算機(jī)中,很多曲線和曲面都可以通過(guò)樣條曲線等參數(shù)曲線來(lái)描述。其中,B樣條(B-Spline)在工業(yè)設(shè)計(jì)中的應(yīng)用十分廣泛[12]。k次B樣條曲線的表達(dá)式如下:
其中ti為節(jié)點(diǎn)值構(gòu)成了樣條曲線的節(jié)點(diǎn)矢量矩陣。
3D設(shè)計(jì)中經(jīng)常包括NURBS(Non-Uniform Ratio?nal B-Spline),非均勻有理B樣條曲線是一個(gè)分段的有理多項(xiàng)式函數(shù),其定義如下:
其中k為冪次,ui(i=0,1,…,m)為節(jié)點(diǎn),當(dāng)冪次=k,控制點(diǎn)數(shù)=n+1,節(jié)點(diǎn)數(shù)=m+1時(shí),可以得到m=n+1。
三維NURBS曲面的定義如下:
定義樣條曲線的求值器P(u),且u∈[0,1],表達(dá)式如下:
其中Pi表示控制點(diǎn),如果u的取值范圍為,求值器的值為:
對(duì)于二維曲面,求值器的表達(dá)式為:
一般來(lái)說(shuō),實(shí)際使用的NURBS曲面和Bezier曲面都少于4次,常用的是3次曲面。B樣條曲面和Bezier曲面都可以通過(guò)調(diào)整控制點(diǎn)來(lái)控制曲面的形狀,造型能力很強(qiáng)。通過(guò)OpenGL實(shí)現(xiàn)的NURBS曲面如圖4所示:
圖4 NURBS曲面
紋理映射實(shí)現(xiàn)就是將一張紋理圖像貼到三維物體表面,就像貼墻紙一樣。下面介紹曲面紋理映射的實(shí)現(xiàn)過(guò)程。
紋理映射的實(shí)現(xiàn)過(guò)程主要包括下面的一些步驟:紋理定義、紋理控制、確定映射方式和紋理坐標(biāo)的確定。
(1)創(chuàng)建紋理:
創(chuàng)建一個(gè)紋理對(duì)象,并將它和紋理單元進(jìn)行綁定?;蛘咧苯幼x取已知的紋理圖像,然后綁定,一般情況下紋理認(rèn)為是二維的。
(2)建立映射函數(shù):
映射函數(shù)用來(lái)表示紋理坐標(biāo)和三維物體坐標(biāo)之間的對(duì)應(yīng)關(guān)系,有參數(shù)表達(dá)式的曲面,可以直接利用它們的參數(shù)表達(dá)式。有時(shí)候也需要利用中間曲面,就是建立到中間曲面的映射函數(shù)。不同的物體之間的映射函數(shù)不一樣,需要建立一個(gè)頂點(diǎn)之間的映射關(guān)系。
(3)設(shè)置映射方式:
設(shè)置紋理映射的顏色參數(shù),有時(shí)可以直接將紋理圖像作為顏色映射到曲面上,紋理就好像被粘貼在曲面上;如果想得到比較好的光照和紋理綜合效果,把景物曲面的顏色或顏色比例和紋理圖像的紋理值結(jié)合,通過(guò)紋理值來(lái)靈活調(diào)整;還可以采用一種混合的方式:把曲面原來(lái)的顏色和一個(gè)固定顏色紋理值進(jìn)行混合。
(4)激活紋理映射:
先對(duì)紋理進(jìn)行處理:與指定顏色和法向量類似,需要為每一個(gè)頂點(diǎn)分配紋理坐標(biāo)。在最終的繪制之前,需要激活紋理映射。
(5)繪制幾何場(chǎng)景:
在進(jìn)行最后的映射之前,需要了解紋理相對(duì)于曲面是怎么排列的,必須指定場(chǎng)景中物體的紋理坐標(biāo)和幾何坐標(biāo)。經(jīng)過(guò)幾何變換之后頂點(diǎn)在屏幕上繪制的位置是由幾何坐標(biāo)決定的,而紋理坐標(biāo)決定紋理圖像中哪個(gè)紋理像素值賦值給該頂點(diǎn)。
實(shí)驗(yàn)以VC++2013為編程環(huán)境,利用OpenGL對(duì)紋理映射技術(shù)進(jìn)行研究和驗(yàn)證。通過(guò)OpenGL實(shí)現(xiàn)了曲面紋理映射,圖4展示了把一個(gè)帶狀紋理映射到茶壺表面的效果圖;Bezier曲面的紋理映射效果如圖5所示:將一個(gè)棋盤(pán)紋理圖像映射到雙三次Bezier曲面上。
圖5茶壺曲面紋理映射
圖6 Bezier曲面上的紋理映射
本文通過(guò)研究曲面紋理映射算法,對(duì)經(jīng)典的紋理映射算法進(jìn)行了總結(jié)和分析;結(jié)合兩步法紋理映射技術(shù),研究了自由曲面和參數(shù)曲面中的紋理映射算法;并利用OpenGL實(shí)現(xiàn)了參數(shù)曲面紋理映射算法,以及對(duì)相關(guān)的曲面紋理映射技術(shù)進(jìn)行了驗(yàn)證。實(shí)驗(yàn)結(jié)果表明,這些紋理映射算法中可能會(huì)產(chǎn)生反走樣現(xiàn)象,這個(gè)問(wèn)題還沒(méi)有很好地解決,還需要深入研究,后續(xù)將著重研究如何減少映射過(guò)程中的反走樣現(xiàn)象,這些研究?jī)?nèi)容對(duì)紋理映射的應(yīng)用有重要意義。