表面的紋理就是它的外觀和感覺(jué)——就像一幅油畫(huà)的紋理革娄。在計(jì)算機(jī)圖形學(xué)中利赋,紋理處理是一種使用圖像郁妈、函數(shù)或其他數(shù)據(jù)源獲取一個(gè)表面并在每個(gè)位置修改其外觀的過(guò)程涡上。例如趾断,不是精確地表示磚墻的幾何形狀,而是將磚墻的彩色圖像應(yīng)用于由兩個(gè)三角形組成的矩形吩愧。當(dāng)矩形被查看時(shí)芋酌,彩色圖像出現(xiàn)在矩形的位置。除非觀者靠近墻壁雁佳,否則缺乏幾何細(xì)節(jié)的問(wèn)題將不會(huì)被注意到脐帝。
然而,一些有紋理的磚墻可能是不令人信服的原因糖权,而不是缺乏幾何形狀堵腹。例如,如果砂漿是啞光的温兼,而磚是光滑的,那么觀察者會(huì)注意到兩種材料的粗糙度是相同的武契。為了產(chǎn)生更真實(shí)的感覺(jué)募判,可以在表面應(yīng)用第二個(gè)圖像紋理。這種紋理不會(huì)改變表面的顏色咒唆,而是根據(jù)表面的位置改變墻壁的粗糙度〗斓妫現(xiàn)在磚塊和砂漿有了來(lái)自圖像紋理的顏色和來(lái)自這個(gè)新紋理的粗糙度值。
觀察者可能會(huì)看到現(xiàn)在所有的磚都是光滑的全释,而砂漿不是装处,但請(qǐng)注意,每個(gè)磚面似乎是完全平坦的浸船。這看起來(lái)不太對(duì)妄迁,因?yàn)榇u塊的表面通常有些不規(guī)則。通過(guò)應(yīng)用凹凸貼圖李命,磚塊的陰影法線(xiàn)可以發(fā)生變化登淘,這樣當(dāng)它們被渲染時(shí),就不會(huì)顯得非常光滑封字。為了計(jì)算光照黔州,這種紋理會(huì)使矩形的原始表面法線(xiàn)方向發(fā)生抖動(dòng)耍鬓。
在比較小的夾角來(lái)看的話(huà),這種凹凸感會(huì)被打破流妻。磚塊應(yīng)該在突出于泥漿牲蜀,擋住視線(xiàn),即使從正面看绅这,磚塊也應(yīng)該在砂漿投下陰影涣达。視差貼圖使用紋理在渲染平面時(shí)使其變形,而視差遮擋貼圖將光線(xiàn)投射到高光場(chǎng)紋理上以提高真實(shí)感君躺。位移映射通過(guò)修改形成模型的三角形高度峭判,真正取代了曲面。圖6.1顯示了一個(gè)帶有顏色紋理和凹凸貼圖的例子棕叫。
這些都是可以用紋理來(lái)解決的問(wèn)題類(lèi)型的例子林螃,使用越來(lái)越復(fù)雜的算法。在本章中俺泣,紋理技術(shù)將被詳細(xì)介紹疗认。首先,給出了紋理處理的一般框架伏钠。接下來(lái)横漏,我們將重點(diǎn)放在使用圖像來(lái)紋理表面,因?yàn)檫@是實(shí)時(shí)工作中使用的最流行的紋理形式熟掂。對(duì)程序紋理進(jìn)行了簡(jiǎn)要的討論缎浇,并介紹了幾種常用的紋理影響曲面的方法。
6.1 紋理管線(xiàn) The Texturing Pipeline
紋理是一種有效地塑造表面材質(zhì)和表面光澤度變化的技術(shù)赴肚∷囟澹考慮紋理的一種方法是考慮單著色像素的情況。正如在前一章中所看到的誉券,著色是通過(guò)考慮材料的顏色和燈光等因素計(jì)算出來(lái)的指厌。如果存在,透明度也會(huì)影響樣本踊跟。紋理是通過(guò)修改著色方程中使用的值來(lái)實(shí)現(xiàn)的踩验。這些值的變化方式通常基于表面的位置商玫。因此箕憾,對(duì)于磚墻的例子來(lái)說(shuō),根據(jù)表面位置拳昌,將表面上任意一點(diǎn)的顏色替換為磚墻圖像中相應(yīng)的顏色厕九。圖像紋理中的像素通常被稱(chēng)為texel,以區(qū)別于屏幕上的像素(pixel)地回。粗糙度紋理修改了粗糙度值扁远,凹凸紋理改變了陰影法線(xiàn)的方向俊鱼,所以這些都改變了著色方程的結(jié)果。
紋理可以用廣義紋理管道來(lái)描述畅买。稍后將介紹許多術(shù)語(yǔ)并闲,但是請(qǐng)記住:將詳細(xì)描述管道的每個(gè)部分。
空間中的位置是紋理處理的起點(diǎn)谷羞。這個(gè)位置可以在世界空間中帝火,但更多的時(shí)候是在模型的參考框架中,所以當(dāng)模型移動(dòng)時(shí)湃缎,紋理也隨之移動(dòng)犀填。使用Kershaw的術(shù)語(yǔ)[884],空間中的這個(gè)點(diǎn)有一個(gè)投影函數(shù)嗓违,用于獲取一組數(shù)字九巡,稱(chēng)為紋理坐標(biāo),用于訪(fǎng)問(wèn)紋理蹂季。這個(gè)過(guò)程稱(chēng)為映射(mapping)冕广,它導(dǎo)致phrase texture mapping。有時(shí)紋理圖像本身被稱(chēng)為紋理映射偿洁,盡管這并不完全正確撒汉。
在使用這些新值訪(fǎng)問(wèn)紋理之前,可以使用一個(gè)或多個(gè)映射函數(shù)將紋理坐標(biāo)轉(zhuǎn)換為紋理空間涕滋。這些紋理空間位置用于從紋理中獲取值睬辐,例如,它們可以是數(shù)組索引到圖像紋理中以檢索像素宾肺。然后溯饵,通過(guò)值轉(zhuǎn)換函數(shù)可能再次轉(zhuǎn)換檢索到的值,最后爱榕,這些新值用于修改表面的某些屬性瓣喊,如材質(zhì)或著色法線(xiàn)坡慌。圖6.2詳細(xì)顯示了單個(gè)紋理應(yīng)用程序的這個(gè)過(guò)程黔酥。管道復(fù)雜性的原因是,每個(gè)步驟都為用戶(hù)提供了一個(gè)有用的部件洪橘。應(yīng)該指出的是跪者,并非所有步驟都需要在任何時(shí)候都被激活。
使用這個(gè)管道熄求,當(dāng)一個(gè)三角形具有磚墻紋理并在其表面生成一個(gè)示例時(shí)渣玲,就會(huì)發(fā)生這種情況(參見(jiàn)圖6.3)。(x, y, z)在目標(biāo)局部參照系中的位置;假設(shè)是(- 2.3,7.1,88.2)然后將投射函數(shù)應(yīng)用于此位置弟晚。就像一幅世界地圖是一個(gè)三維物體的二維投影,投影函數(shù)通常改變(x, y, z)向量成雙元素向量(u, v)忘衍。本例中使用的投影儀功能相當(dāng)于一個(gè)正射投影(2.3.1節(jié)),作用類(lèi)似幻燈機(jī)閃亮的磚墻上三角形的表面形象逾苫。要返回到壁面,可以將壁面上的一個(gè)點(diǎn)轉(zhuǎn)換成一對(duì)值枚钓,取值范圍從0到1铅搓。假設(shè)得到的值是(0.32,0.29)。這些紋理坐標(biāo)將被用來(lái)找出在這個(gè)位置的圖像的顏色搀捷。例如星掰,磚塊紋理的分辨率是256×256,因此對(duì)應(yīng)函數(shù)將(u, v)分別乘以256嫩舟,得到(81.92,74.24)氢烘。去除分?jǐn)?shù)后,磚墻圖像中出現(xiàn)像素(81,74)家厌,顏色為(0.9,0.8,0.7)播玖。紋理顏色在sRGB顏色空間中,因此如果要在陰影方程中使用顏色像街,則將其轉(zhuǎn)換為線(xiàn)性空間黎棠,給出(0.787,0.604,0.448)(第5.6節(jié))。
6.1.1 投影函數(shù) The Projector Function
紋理處理的第一步是獲取曲面的位置镰绎,并將其投影到紋理坐標(biāo)空間中脓斩,通常是二維(u, v)空間。建模包通常允許藝術(shù)家定義(u, v)每個(gè)頂點(diǎn)的坐標(biāo)畴栖。這些可以從投影方法或網(wǎng)格展開(kāi)算法初始化随静。美工可以編輯(u, v)坐標(biāo),就像編輯頂點(diǎn)位置一樣吗讶。投影儀的功能通常是通過(guò)將空間中的三維點(diǎn)轉(zhuǎn)換為紋理坐標(biāo)來(lái)實(shí)現(xiàn)的燎猛。建模程序中常用的函數(shù)包括球面、圓柱和平面投影[141,88,970]照皆。
其他輸入可用于投影函數(shù)重绷。例如,表面法線(xiàn)可以用來(lái)選擇六個(gè)平面投影方向中的哪一個(gè)用于表面膜毁。紋理匹配問(wèn)題發(fā)生在面相接的接縫處;Geiss[521,522]討論了一種混合它們的技術(shù)昭卓。Tarini等[1740]描述了多立方體映射,其中模型映射到一組立方體投影瘟滨,不同體積的空間映射到不同的立方體候醒。
其他投影函數(shù)根本不是投影,而是表面創(chuàng)建和棋盤(pán)格的一個(gè)指導(dǎo)部分杂瘸。例如倒淫,參數(shù)曲面有一組(u, v)值作為其定義的一部分。參見(jiàn)圖6.4败玉。紋理坐標(biāo)還可以由各種不同的參數(shù)生成敌土,比如視圖方向镜硕、表面溫度或任何可以想象的東西。投影函數(shù)的目標(biāo)是生成紋理坐標(biāo)返干。把這些作為位置的函數(shù)只是一種方法谦疾。
非交互式渲染器通常將這些投影函數(shù)作為渲染過(guò)程本身的一部分進(jìn)行調(diào)用。一個(gè)單一的投影函數(shù)可以滿(mǎn)足整個(gè)模型犬金,但藝術(shù)家往往不得不使用工具細(xì)分模型念恍,并分別應(yīng)用不同的投影函數(shù)[1345]。參見(jiàn)圖6.5晚顷。
在實(shí)時(shí)渲染中峰伙,通常在建模階段使用投影函數(shù),將投影結(jié)果存儲(chǔ)在頂點(diǎn)上该默。情況并非總是如此;有時(shí)在頂點(diǎn)或像素著色器中應(yīng)用投影函數(shù)是有利的瞳氓。這樣做可以提高精度,并幫助啟用各種效果栓袖,包括動(dòng)畫(huà)(第6.4節(jié))匣摘。有些渲染方法,如環(huán)境映射(10.4節(jié))裹刮,具有自己的特殊投影函數(shù)音榜,這些函數(shù)按像素計(jì)算。
球面投影(圖6.4中的左邊)將點(diǎn)投射到以某個(gè)點(diǎn)為中心的假想球體上捧弃。這個(gè)投影與Blinn和Newell的環(huán)境映射方案中使用的是相同的(第10.4.1節(jié))赠叼,所以407頁(yè)的方程10.30描述了這個(gè)函數(shù)。這種投影方法也存在與該節(jié)中描述的頂點(diǎn)插值相同的問(wèn)題违霞。
圓柱投影計(jì)算的u紋理坐標(biāo)與球面投影相同褐啡,v紋理坐標(biāo)計(jì)算的是沿圓柱軸線(xiàn)的距離牵咙。這種投影對(duì)于具有自然軸的物體很有用躲庄,比如旋轉(zhuǎn)面预愤。當(dāng)表面接近垂直于圓柱體軸線(xiàn)時(shí),就會(huì)發(fā)生畸變眼五。
平面投影就像一束x射線(xiàn)妆艘,沿著一個(gè)方向平行投影,并將紋理應(yīng)用于所有表面弹砚。它使用正投影(第4.7.1節(jié))双仍。這種類(lèi)型的投影適用于貼花枢希,例如(第20.2節(jié))桌吃。
由于與投影方向平行的表面存在嚴(yán)重的失真,藝術(shù)家通常必須手工將模型分解成接近平面的部分苞轿。還有一些工具可以通過(guò)展開(kāi)網(wǎng)格或創(chuàng)建一組近乎最優(yōu)的平面投影來(lái)幫助最小化失真茅诱,或者幫助這個(gè)過(guò)程逗物。我們的目標(biāo)是讓每個(gè)多邊形在紋理的區(qū)域中得到更公平的份額,同時(shí)盡可能保持網(wǎng)格的連通性瑟俭。連接性很重要翎卓,因?yàn)椴蓸庸ぜ梢猿霈F(xiàn)在紋理的不同部分相遇的邊緣。一個(gè)可以很好地展開(kāi)的網(wǎng)格也可以使藝術(shù)家創(chuàng)造作品變得更容易[970,1345]摆寄。第16.2.1節(jié)討論了紋理失真對(duì)渲染的負(fù)面影響失暴。圖6.6顯示了用于創(chuàng)建圖6.5中雕像的工作區(qū)。這種展開(kāi)過(guò)程是網(wǎng)格參數(shù)化這一更大研究領(lǐng)域的一個(gè)方面微饥。感興趣的讀者可以參考Hormann等人的SIGGRAPH課程筆記[774]逗扒。
紋理坐標(biāo)空間并不總是二維平面;有時(shí)它是一個(gè)三維體。在這種情況下欠橘,紋理坐標(biāo)表示為一個(gè)三元素向量(u, v,w)矩肩, w是沿投影方向的深度。其他系統(tǒng)最多使用四個(gè)坐標(biāo)肃续,通常指定(s, t, r, q) [885];q是齊次坐標(biāo)中的第四個(gè)值黍檩。它就像電影或幻燈片放映機(jī)一樣,投影紋理的大小隨著距離的增加而增加始锚。例如刽酱,它可以將一種稱(chēng)為gobo的裝飾性聚光燈圖案投射到舞臺(tái)或其他表面上[1597]。
紋理坐標(biāo)空間的另一種重要類(lèi)型是方向瞧捌,其中空間中的每個(gè)點(diǎn)都由輸入方向訪(fǎng)問(wèn)肛跌。將這樣的空間可視化的一種方法是在一個(gè)單位球上的點(diǎn),每個(gè)點(diǎn)上的法線(xiàn)表示用于訪(fǎng)問(wèn)該位置紋理的方向察郁。使用方向參數(shù)化的最常見(jiàn)紋理類(lèi)型是立方體映射(第6.2.4節(jié))衍慎。
同樣值得注意的是,一維紋理圖像和函數(shù)也有它們的用途皮钠。例如稳捆,在地形模型上,顏色可以由高度決定麦轰,例如乔夯,低地是綠色的;山峰是白色的。線(xiàn)也可以紋理映射;它的一個(gè)用途是將雨渲染為一組帶有半透明圖像紋理的長(zhǎng)線(xiàn)條款侵。這樣的紋理對(duì)于從一個(gè)值到另一個(gè)值的轉(zhuǎn)換也很有用末荐。例如,作為查找表新锈。
由于一個(gè)表面可以應(yīng)用多個(gè)紋理甲脏,因此可能需要定義多個(gè)紋理坐標(biāo)集。無(wú)論如何應(yīng)用坐標(biāo)值,其思想都是一樣的:這些紋理坐標(biāo)在整個(gè)表面內(nèi)插并用于檢索紋理值块请。然而娜氏,在插值之前,這些紋理坐標(biāo)被相應(yīng)的函數(shù)轉(zhuǎn)換墩新。
6.12 映射函數(shù) The Corresponder Function
映射函數(shù)將紋理坐標(biāo)轉(zhuǎn)換為紋理空間位置贸弥。它們提供了將紋理應(yīng)用到表面的靈活性。映射函數(shù)的一個(gè)例子是使用API選擇要顯示的現(xiàn)有紋理的一部分;只有這個(gè)子圖像將在后續(xù)操作中使用海渊。
另一種類(lèi)型的映射器是矩陣變換绵疲,它可以應(yīng)用于頂點(diǎn)著色器或像素著色器。這使移動(dòng)臣疑,旋轉(zhuǎn)最岗,縮放,剪切朝捆,或投射紋理的表面般渡。正如第4.1.5節(jié)所討論的,轉(zhuǎn)換的順序很重要芙盘。令人驚訝的是驯用,紋理的轉(zhuǎn)換順序必須與我們所期望的順序相反。這是因?yàn)榧y理變換實(shí)際上影響了決定圖像位置的空間儒老。圖像本身不是被轉(zhuǎn)換的對(duì)象;定義圖像位置的空間正在更改蝴乔。
另一類(lèi)映射函數(shù)控制應(yīng)用圖像的方式。我們知道一個(gè)圖像會(huì)出現(xiàn)在(u, v)在[0,1]范圍內(nèi)的表面驮樊。但是在這個(gè)范圍之外會(huì)發(fā)生什么呢?對(duì)應(yīng)函數(shù)決定行為薇正。在OpenGL中,這種類(lèi)型的通信器函數(shù)稱(chēng)為“Wrapping mode”;在DirectX中囚衔,它被稱(chēng)為“texture addressing mode”挖腰。這類(lèi)常見(jiàn)的對(duì)應(yīng)函數(shù)有:
Wrap(DirectX)、Repeat(OpenGL)或tile——圖像在表面上重復(fù)自己;算法上练湿,刪除紋理坐標(biāo)的整數(shù)部分猴仑。這個(gè)函數(shù)對(duì)于讓一個(gè)物體的圖像重復(fù)地覆蓋一個(gè)表面很有用,并且通常是默認(rèn)值肥哎。
mirror——圖像在表面上重復(fù)辽俗,但在每一次重復(fù)時(shí)都會(huì)被鏡像(翻轉(zhuǎn))。例如篡诽,圖像通常從0到1崖飘,然后在1和2之間反轉(zhuǎn),然后在2和3之間正常杈女,然后反轉(zhuǎn)朱浴,以此類(lèi)推吊圾。這提供了沿著紋理邊緣的連續(xù)性。
clamp(DirectX)或clamp to edge(OpenGL) -范圍[0,1]以外的值被鉗位到這個(gè)范圍赊琳。這導(dǎo)致圖像紋理邊緣的重復(fù)。當(dāng)雙線(xiàn)性插值發(fā)生在紋理邊緣附近時(shí)砰碴,該函數(shù)有助于避免意外地從紋理的相對(duì)邊緣提取樣本[885]躏筏。
border (DirectX)或clamp to border (OpenGL) -外邊的紋理坐標(biāo)[0,1]用單獨(dú)定義的邊框顏色呈現(xiàn)。例如呈枉,這個(gè)函數(shù)可以很好地在單色表面上呈現(xiàn)貼花趁尼,因?yàn)榧y理的邊緣將與邊框顏色平滑地混合。
參見(jiàn)圖6.7猖辫。這些對(duì)應(yīng)的函數(shù)可以為每個(gè)紋理軸分配不同的值酥泞,例如紋理可以沿著u軸重復(fù),也可以?shī)A在v軸上啃憎。在DirectX中芝囤,還有一個(gè)mirror once模式,它沿著紋理坐標(biāo)的零值對(duì)紋理進(jìn)行一次鏡像辛萍,然后進(jìn)行clamp悯姊,這對(duì)于對(duì)稱(chēng)貼花非常有用。
重復(fù)平鋪紋理是一種為場(chǎng)景添加更多視覺(jué)細(xì)節(jié)的廉價(jià)方法贩毕。然而悯许,這種方法在重復(fù)三次紋理之后,通郴越祝看起來(lái)并不令人信服先壕,因?yàn)檠劬?huì)識(shí)別出圖案。避免這種周期性問(wèn)題的常見(jiàn)解決方案是將紋理值與另一個(gè)非平鋪紋理相結(jié)合谆甜。這種方法可以得到很大的擴(kuò)展垃僚,如Andersson[40]描述的商業(yè)地形繪制系統(tǒng)所示。在該系統(tǒng)中规辱,根據(jù)地形類(lèi)型冈在、高度、坡度等因素按摘,將多種紋理進(jìn)行組合包券。紋理圖像還與幾何模型(如灌木叢和巖石)在場(chǎng)景中的位置相關(guān)聯(lián)。
避免周期性的另一個(gè)選擇是使用著色器程序來(lái)實(shí)現(xiàn)特殊的對(duì)應(yīng)函數(shù)炫贤,這些函數(shù)隨機(jī)地重新組合紋理模式或tile溅固。Wang tiles就是這種方法的一個(gè)例子。Wang tile是一組邊緣匹配的正方形小瓦片兰珍。在紋理處理過(guò)程中侍郭,瓷磚是隨機(jī)選擇的[1860]。Lefebvre和Neyret[1016]使用依賴(lài)的紋理讀取和表實(shí)現(xiàn)了類(lèi)似類(lèi)型的對(duì)應(yīng)函數(shù),以避免模式重復(fù)亮元。
最后一個(gè)對(duì)應(yīng)函數(shù)是隱式的猛计,由圖像的大小導(dǎo)出。紋理通常應(yīng)用在u和v的[0,1]范圍內(nèi)爆捞,如磚墻例子所示奉瘤,將這個(gè)范圍內(nèi)的紋理坐標(biāo)乘以圖像的分辨率,就可以得到像素位置煮甥。能夠在[0,1]范圍內(nèi)指定(u, v)值的好處是可以交換具有不同分辨率的圖像紋理盗温,而不必更改存儲(chǔ)在模型頂點(diǎn)上的值。
6.1.3 紋理值 Texture Values
在使用相應(yīng)的函數(shù)生成紋理空間坐標(biāo)后成肘,使用坐標(biāo)獲取紋理值卖局。對(duì)于圖像紋理,這是通過(guò)訪(fǎng)問(wèn)紋理來(lái)從圖像中檢索texel信息來(lái)實(shí)現(xiàn)的双霍。第6.2節(jié)詳細(xì)討論了這一過(guò)程砚偶。圖像紋理在實(shí)時(shí)渲染中占絕大多數(shù),但也可以使用程序化函數(shù)洒闸。在程序化紋理的情況下蟹演,從紋理空間位置獲取紋理值的過(guò)程不涉及內(nèi)存查找,而是一個(gè)函數(shù)的計(jì)算顷蟀。程序紋理將在6.3節(jié)中進(jìn)一步描述酒请。
最直接的紋理值是用于替換或修改表面顏色的RGB三元組;類(lèi)似地,可以返回單個(gè)灰度值鸣个。另一種類(lèi)型的數(shù)據(jù)返回RGBα,如5.5節(jié)所述羞反。α(阿爾法)值通常是不透明的顏色,決定在多大程度上可能影響像素的顏色。也就是說(shuō)囤萤,任何其他值都可以存儲(chǔ)昼窗,比如表面粗糙度。還有許多其他類(lèi)型的數(shù)據(jù)可以存儲(chǔ)在圖像紋理中涛舍,我們將在詳細(xì)討論凹凸貼圖時(shí)看到(第6.7節(jié))澄惊。
從紋理返回的值在使用之前可選地進(jìn)行轉(zhuǎn)換。這些轉(zhuǎn)換可以在著色器程序中執(zhí)行富雅。一個(gè)常見(jiàn)的例子是將數(shù)據(jù)從無(wú)符號(hào)范圍(0.0到1.0)映射到有符號(hào)范圍(- 1.0到1.0)掸驱,用于對(duì)存儲(chǔ)在顏色紋理中的法線(xiàn)進(jìn)行著色。
6.2 圖像紋理映射 Image Texturing
在圖像紋理處理中没佑,二維圖像被有效地粘在一個(gè)或多個(gè)三角形的表面上毕贼。我們已經(jīng)完成了計(jì)算文本位置的過(guò)程;現(xiàn)在,我們將討論從給定位置的圖像紋理中獲取紋理值的問(wèn)題和算法蛤奢。在本章的其余部分鬼癣,圖像紋理將被簡(jiǎn)單地稱(chēng)為紋理陶贼。此外,當(dāng)我們?cè)谶@里提到像素的單元格時(shí)待秃,我們指的是圍繞該像素的屏幕網(wǎng)格單元格拜秧。正如第5.4.1節(jié)所討論的,像素實(shí)際上是一個(gè)顯示的顏色值章郁,它可以(而且應(yīng)該枉氮,為了更好的質(zhì)量)受到與其相關(guān)的網(wǎng)格單元外部樣本的影響。
在本節(jié)中驱犹,我們特別關(guān)注快速采樣和過(guò)濾紋理圖像的方法嘲恍。第5.4.2節(jié)討論了混疊問(wèn)題足画,特別是對(duì)象的邊緣渲染問(wèn)題雄驹。紋理也可能有采樣問(wèn)題,但它們發(fā)生在正在呈現(xiàn)的三角形的內(nèi)部淹辞。
像素著色器通過(guò)將紋理坐標(biāo)值傳遞給texture2D之類(lèi)的調(diào)用來(lái)訪(fǎng)問(wèn)紋理医舆。這些值位于(u, v)紋理坐標(biāo)中,由對(duì)應(yīng)函數(shù)映射到范圍[0.0,1.0]象缀。GPU負(fù)責(zé)將這個(gè)值轉(zhuǎn)換為texel坐標(biāo)蔬将。在不同的api中,紋理坐標(biāo)系有兩個(gè)主要區(qū)別央星。在DirectX中霞怀,紋理的左上角是(0,0),右下角是(1,1)莉给。在OpenGL中毙石,texel(0,0)位于左下角,從DirectX翻轉(zhuǎn)y軸颓遏。texel具有整數(shù)坐標(biāo)徐矩,但我們通常希望訪(fǎng)問(wèn)texel之間的一個(gè)位置并在其中進(jìn)行混合。這就引出了一個(gè)問(wèn)題:像素中心的浮點(diǎn)坐標(biāo)是什么叁幢。Heckbert[692]討論了兩種可能的系統(tǒng):截?cái)嗪蜕崛肼说啤irectX 9將每個(gè)中心定義為(0.0,0.0)—這使用四舍五入。這個(gè)系統(tǒng)有點(diǎn)令人困惑曼玩,因?yàn)樵贒irectX的原點(diǎn)處鳞骤,左上角的像素值為(- 0.5,- 0.5)黍判。DirectX 10繼續(xù)修改OpenGL的系統(tǒng)弟孟,其中texel的中心有分?jǐn)?shù)值(0.5,0.5)-截?cái)啵蛘吒鼫?zhǔn)確地說(shuō)样悟,floor拂募,分?jǐn)?shù)被刪除庭猩。floor是一個(gè)更自然的系統(tǒng),可以很好地映射到語(yǔ)言陈症,例如蔼水,在那個(gè)像素(5,9)中,定義了一個(gè)范圍录肯,u坐標(biāo)為5.0到6.0,v坐標(biāo)為9.0到10.0趴腋。
當(dāng)通過(guò)texture2D或類(lèi)似的方法訪(fǎng)問(wèn)紋理時(shí),當(dāng)像素著色器計(jì)算紋理坐標(biāo)而不是使用頂點(diǎn)著色器傳入的未經(jīng)修改的紋理坐標(biāo)時(shí)论咏,就會(huì)發(fā)生依賴(lài)的紋理讀取[66]优炬。注意,這意味著對(duì)傳入的紋理坐標(biāo)進(jìn)行任何更改厅贪,即使是交換u和v值這樣的簡(jiǎn)單操作蠢护。舊的移動(dòng)gpu,那些不支持OpenGL ES 3.0的gpu养涮,在著色器沒(méi)有依賴(lài)紋理讀取時(shí)運(yùn)行得更有效率葵硕,因?yàn)殡S后可以預(yù)取texel數(shù)據(jù)。這個(gè)術(shù)語(yǔ)的另一個(gè)更古老的定義對(duì)于早期的桌面gpu尤其重要贯吓。在這個(gè)上下文中懈凹,當(dāng)一個(gè)紋理的坐標(biāo)依賴(lài)于之前一些紋理值的結(jié)果時(shí),就會(huì)發(fā)生依賴(lài)紋理讀取悄谐。例如介评,一個(gè)紋理可能會(huì)更改著色法線(xiàn),這反過(guò)來(lái)又會(huì)更改用于訪(fǎng)問(wèn)多維數(shù)據(jù)集映射的坐標(biāo)爬舰。這種功能在早期的gpu上是有限的们陆,甚至是不存在的。今天洼专,這種讀取可能會(huì)影響性能棒掠,這取決于在批處理中計(jì)算的像素?cái)?shù)量以及其他因素。有關(guān)更多信息屁商,請(qǐng)參見(jiàn)第23.8節(jié)烟很。
gpu中使用的紋理圖像大小通常為2m×2n個(gè)紋理,其中m和n是非負(fù)整數(shù)蜡镶。這些被稱(chēng)為2的冪(POT)紋理∥砀ぃ現(xiàn)代gpu可以處理任意大小的非二冪(NPOT)紋理,這允許將生成的圖像作為紋理處理官还。然而芹橡,一些較老的移動(dòng)gpu可能不支持NPOT紋理的mipmapping(第6.2.2節(jié))。圖形加速器在紋理大小上有不同的上限望伦。例如林说,directx12最多允許163842個(gè)texel煎殷。
假設(shè)我們有一個(gè)大小為256×256的紋理,并且我們想使用它作為正方形上的紋理腿箩。只要投影在屏幕上的正方形與紋理大小大致相同豪直,那么正方形上的紋理看起來(lái)就幾乎與原始圖像一樣。但是珠移,如果投影的正方形所覆蓋的像素是原始圖像所包含像素的十倍(稱(chēng)為放大)弓乙,或者投影的正方形只覆蓋屏幕的一小部分(縮小),又會(huì)發(fā)生什么呢?答案是钧惧,這取決于您決定對(duì)這兩個(gè)單獨(dú)的情況使用哪種抽樣和過(guò)濾方法暇韧。
本章討論的圖像采樣和濾波方法適用于從每個(gè)紋理中讀取的值。然而浓瞪,期望的結(jié)果是防止最終呈現(xiàn)的圖像中的混疊懈玻,這在理論上需要采樣和過(guò)濾最終像素的顏色。這里的區(qū)別是過(guò)濾著色方程的輸入追逮,還是過(guò)濾輸出酪刀。只要輸入和輸出是線(xiàn)性相關(guān)的(這對(duì)于輸入來(lái)說(shuō)是正確的粹舵,比如顏色)钮孵,那么過(guò)濾單獨(dú)的紋理值就相當(dāng)于過(guò)濾最終的顏色。然而眼滤,許多存儲(chǔ)在紋理中的著色器輸入值巴席,如表面法線(xiàn)和粗糙度值,與輸出有非線(xiàn)性關(guān)系诅需。標(biāo)準(zhǔn)的紋理過(guò)濾方法可能對(duì)這些紋理不起作用漾唉,導(dǎo)致混疊。第9.13節(jié)討論了過(guò)濾這些紋理的改進(jìn)方法堰塌。
6.2.1 放大 Magnification
在圖6.8中赵刑,一個(gè)尺寸為48×48 texels的紋理被紋理化到一個(gè)正方形上,相對(duì)于紋理大小场刑,這個(gè)正方形被看得很近般此,因此底層的圖形系統(tǒng)必須放大紋理。放大最常用的濾波技術(shù)是最近鄰(實(shí)際的濾波器稱(chēng)為框式濾波器box filter——見(jiàn)5.4.1節(jié))和雙線(xiàn)性插值(bilinear interpolation)牵现。還有三次卷積铐懊,它使用4×4或5×5個(gè)紋理數(shù)組的加權(quán)和。這使得更高的放大質(zhì)量瞎疼。雖然本地硬件支持三次卷積(也稱(chēng)為雙三次插值 bicubic interpolation)目前并不常見(jiàn)科乎,但它可以在著色器程序中執(zhí)行。
在圖6.8的左側(cè)贼急,使用了最近鄰方法茅茂。這種放大技術(shù)的一個(gè)特點(diǎn)是單個(gè)紋理可能變得明顯捏萍。這種效果稱(chēng)為像素化,之所以會(huì)發(fā)生這種情況空闲,是因?yàn)樵摲椒ㄔ诜糯髸r(shí)取距離每個(gè)像素中心最近的texel的值照弥,從而產(chǎn)生塊狀外觀。雖然這種方法的質(zhì)量有時(shí)很差进副,但它只需要為每個(gè)像素獲取一個(gè)texel这揣。
在同一圖形的中間圖像中,使用雙線(xiàn)性插值(有時(shí)稱(chēng)為線(xiàn)性插值)影斑。對(duì)于每個(gè)像素给赞,這種濾波找到四個(gè)相鄰的紋理,并在二維中進(jìn)行線(xiàn)性插值矫户,找到像素的混合值片迅。結(jié)果更加模糊,使用最近鄰方法產(chǎn)生的鋸齒已經(jīng)消失皆辽。作為一個(gè)實(shí)驗(yàn)柑蛇,試著在瞇眼的時(shí)候看左邊的圖片,因?yàn)檫@和低通濾波器的效果差不多驱闷,而且更能顯示臉部耻台。
回到第170頁(yè)的磚塊紋理示例:在不降低分?jǐn)?shù)的情況下,我們得到(pu, pv) =(81.92, 74.24)空另。我們?cè)谶@里使用OpenGL的左下角原點(diǎn)texel坐標(biāo)系盆耽,因?yàn)樗c標(biāo)準(zhǔn)的笛卡爾坐標(biāo)系相匹配。我們的目標(biāo)是在四個(gè)最近的texel之間進(jìn)行插值扼菠,使用它們的texel中心定義一個(gè)texel大小的坐標(biāo)系統(tǒng)摄杂。參見(jiàn)圖6.9。為了找到最近的4個(gè)像素循榆,我們從樣本位置減去像素中心分?jǐn)?shù)(0.5,0.5)析恢,得到(81.42,73.74)。去掉分?jǐn)?shù)后秧饮,最近的四個(gè)像素的范圍從(x, y) =(81,73)到(x+1, y+1) =(82,74)映挂。分?jǐn)?shù)部分(0.42,0.74)對(duì)于我們的例子來(lái)說(shuō),是樣本相對(duì)于四個(gè)texel中心形成的坐標(biāo)系的位置浦楣。我們把這個(gè)位置表示為(u‘袖肥, v’)
將紋理訪(fǎng)問(wèn)函數(shù)定義為t(x, y),其中x和y是整數(shù)振劳,返回texel的顏色椎组。任何位置(u ‘, v ‘)的bilinearly插值顏色都可以計(jì)算為一個(gè)兩步過(guò)程历恐。首先,texel底部,t (x, y)和t (x + 1, y),將被內(nèi)插水平(使用u′),最高的兩個(gè)texel同樣,t (x, y + 1)和t (x + 1, + 1)寸癌。為texel底部,我們獲得(1?u′) t (x, y) + u′t (x + 1, y)(下圖綠色圓圈圖6.9),頂部,(1?u′) t (x, y + 1) + u′t (x + 1, + 1)(綠色圓圈)专筷。這兩個(gè)值然后垂直插值(使用v ‘),因此bilinearly插值的顏色b在(pu, pv)處為
直觀地說(shuō),靠近示例位置的texel會(huì)對(duì)其最終值產(chǎn)生更大的影響。這就是我們?cè)谶@個(gè)方程中看到的疚脐。右上角的texel (x+1, y+1)對(duì)u ‘ v ‘有影響。注意對(duì)稱(chēng)性:右上角的影響等于左下角與采樣點(diǎn)形成的矩形面積味咳。回到我們的示例檬嘀,這意味著從這個(gè)texel檢索到的值將乘以0.42×0.74槽驶,具體來(lái)說(shuō)就是0.3108。從這個(gè)texel順時(shí)針?lè)较蛟蓿渌朔ㄆ鞣謩e為0.42×0.26掂铐、0.58×0.26和0.58×0.74,所有四個(gè)權(quán)值之和為1.0揍异。
對(duì)于伴隨放大而來(lái)的模糊全陨,一個(gè)常見(jiàn)的解決方案是使用細(xì)節(jié)紋理。這些紋理代表了精細(xì)的表面細(xì)節(jié)衷掷,從手機(jī)上的劃痕到地形上的灌木叢辱姨。這樣的細(xì)節(jié)被疊加到放大的紋理上,作為一個(gè)單獨(dú)的紋理棍鳖,在不同的尺度上炮叶。細(xì)節(jié)紋理的高頻重復(fù)圖案碗旅,結(jié)合低頻放大紋理渡处,具有類(lèi)似于使用單一高分辨率紋理的視覺(jué)效果。
雙線(xiàn)性插值在兩個(gè)方向上線(xiàn)性插值祟辟。然而医瘫,不需要線(xiàn)性插值。例如旧困,一個(gè)紋理由棋盤(pán)圖案中的黑白像素組成醇份。使用雙線(xiàn)性插值可以得到不同灰度的紋理樣本。通過(guò)重新映射吼具,例如僚纷,所有低于0.4的灰色都是黑色,所有高于0.6的灰色都是白色拗盒,而那些介于兩者之間的灰色被拉伸來(lái)填補(bǔ)空白怖竭,紋理看起來(lái)更像棋盤(pán)格,同時(shí)也給了紋理之間一些混合陡蝇。參見(jiàn)圖6.10痊臭。
使用高分辨率紋理也會(huì)有類(lèi)似的效果哮肚。例如,假設(shè)每個(gè)檢查器正方形由4×4個(gè)文本組成广匙,而不是1×1允趟。圍繞每個(gè)檢查器的中心,插入的顏色將完全是黑色或白色鸦致。
在圖6.8的右邊潮剪,使用了一個(gè)雙三次濾波器,剩余的塊度基本上被去掉了分唾。值得注意的是鲁纠,雙三次濾波器比雙線(xiàn)性濾波器消耗更高。然而鳍寂,許多高階濾波器可以表示為重復(fù)線(xiàn)性插值[1518] (也參見(jiàn)第17.1.1節(jié))改含。因此,紋理單元中用于線(xiàn)性插值的GPU硬件可以通過(guò)幾個(gè)查找來(lái)使用迄汛。
如果雙三次的過(guò)濾器被認(rèn)為過(guò)于昂貴,Qu′?lez[1451]提出了一種簡(jiǎn)單的方法用光滑曲線(xiàn)之間插入一組2×2 texel捍壤。我們首先描述曲線(xiàn),然后是技術(shù)鞍爱。兩種常用的曲線(xiàn)是平滑階躍曲線(xiàn)和五次曲線(xiàn)[1372]:
當(dāng)您想要平滑地從一個(gè)值插入到另一個(gè)值時(shí)鹃觉,這些方法非常有用。光滑階躍曲線(xiàn)具有s ‘ (0) = s ‘(1) = 0的性質(zhì)睹逃,且在0和1之間光滑盗扇。五次曲線(xiàn)具有相同的性質(zhì),但q ” (0) = q “(1) = 0沉填,即疗隶,二階導(dǎo)數(shù)在曲線(xiàn)的起點(diǎn)和終點(diǎn)也是0。這兩條曲線(xiàn)如圖6.11所示翼闹。
該技術(shù)首先計(jì)算(u ‘斑鼻, v ‘)(與公式6.1和圖6.9中使用的方法相同),首先將樣本乘以紋理尺寸并添加0.5猎荠。整數(shù)部分保留到后面坚弱,分?jǐn)?shù)存儲(chǔ)在u ‘和v ‘中,其取值范圍為[0,1]关摇。然后將(u ‘荒叶, v ‘)轉(zhuǎn)換為(tu, tv) = (q(u ‘), q(v ‘))输虱,仍然在[0,1]的范圍內(nèi)些楣。最后,減去0.5,再把整數(shù)部分加回去;然后得到的u坐標(biāo)除以紋理寬度戈毒,與v類(lèi)似艰猬,此時(shí),新的紋理坐標(biāo)與GPU提供的雙線(xiàn)性插值查找一起使用埋市。注意冠桃,這個(gè)方法將在每個(gè)texel處給出一個(gè)平臺(tái),這意味著道宅,如果texel位于RGB空間中的一個(gè)平面上食听,那么這種類(lèi)型的插值將會(huì)給出一個(gè)光滑的,但仍然是階梯狀的外觀污茵,這可能并不總是需要的樱报。參見(jiàn)圖6.12。
6.2.2 縮小 Minification
當(dāng)紋理最小化時(shí)泞当,幾個(gè)紋理可能覆蓋一個(gè)像素的單元格迹蛤,如圖6.13所示。要為每個(gè)像素獲得正確的顏色值襟士,您應(yīng)該集成紋理對(duì)像素的影響盗飒。然而,要精確地確定一個(gè)特定像素附近的所有文本的確切影響是困難的陋桂,而且實(shí)際上不可能實(shí)時(shí)完美地做到這一點(diǎn)逆趣。
由于這個(gè)限制,在gpu上使用了幾種不同的方法嗜历。一種方法是使用最近鄰宣渗,其工作原理與相應(yīng)的放大濾波器完全相同,即梨州,它選擇在像素單元的中心可見(jiàn)的texel痕囱。這種濾波器可能會(huì)導(dǎo)致嚴(yán)重的混疊問(wèn)題。在圖6.14中摊唇,最上面的圖中使用了最鄰近紋理咐蝇。在水平線(xiàn)處,由于影響一個(gè)像素的眾多紋理中只有一個(gè)被選擇來(lái)表示表面巷查,所以出現(xiàn)了偽影。當(dāng)表面相對(duì)于觀察者移動(dòng)時(shí)抹腿,這樣的偽影更加明顯岛请,并且是所謂的累積混疊(temporal aliasing)的一種表現(xiàn)。
另一種常用的濾波器是雙線(xiàn)性插值警绩,其工作原理與放大濾波器完全相同崇败。這個(gè)過(guò)濾器只比最小化的最近鄰方法稍微好一點(diǎn)。它混合了四個(gè)紋理而不是僅僅使用一個(gè),但是當(dāng)一個(gè)像素受到四個(gè)以上的紋理的影響時(shí)后室,過(guò)濾器很快就會(huì)失效并產(chǎn)生混疊缩膝。
更好的解決方案是可能的。如5.4.1節(jié)所述岸霹,混疊問(wèn)題可以通過(guò)采樣和濾波技術(shù)來(lái)解決疾层。紋理的信號(hào)頻率取決于其紋理在屏幕上的間距。由于Nyquist限制贡避,我們需要確保紋理的信號(hào)頻率不大于采樣頻率的一半痛黎。例如,假設(shè)一個(gè)圖像是由交替的黑白線(xiàn)組成的刮吧,中間有一個(gè)texel湖饱。然后波長(zhǎng)是兩個(gè)texel寬(從黑線(xiàn)到黑線(xiàn)),所以頻率是1/2杀捻。若要在屏幕上正確顯示此紋理井厌,則頻率必須至少為2×1/2,即致讥,每個(gè)texel至少有一個(gè)像素旗笔。所以,對(duì)于一般的紋理拄踪,每個(gè)像素最多應(yīng)該有一個(gè)texel來(lái)避免混疊蝇恶。
為了達(dá)到這個(gè)目的,要么提高像素的采樣頻率惶桐,要么降低紋理頻率撮弧。 前一章討論的抗混疊方法給出了提高像素采樣率的方法。然而姚糊,這些只給出了有限的增加采樣頻率贿衍。為了更好地解決這一問(wèn)題,各種紋理細(xì)化算法應(yīng)運(yùn)而生救恨。
所有紋理反鋸齒算法的基本思想都是一樣的:預(yù)處理紋理并創(chuàng)建數(shù)據(jù)結(jié)構(gòu)贸辈,這些數(shù)據(jù)結(jié)構(gòu)將幫助計(jì)算一組紋理對(duì)像素的效果的快速近似。對(duì)于實(shí)時(shí)渲染肠槽,這些算法具有使用固定時(shí)間和資源執(zhí)行的特點(diǎn)擎淤。通過(guò)這種方法,每個(gè)像素都有固定數(shù)量的樣本秸仙,并結(jié)合起來(lái)計(jì)算(潛在的巨大)數(shù)量的texel的效果嘴拢。
Mipmapping
最流行的紋理抗混疊方法是mipmapping[1889]。它以某種形式在現(xiàn)在生成的所有圖形加速器上實(shí)現(xiàn)寂纪∠猓“Mip”在parvo中代表multum赌结,在拉丁語(yǔ)中是“很多東西在一個(gè)小地方”的意思——這是一個(gè)很好的名字,用來(lái)描述一個(gè)過(guò)程孝冒,在這個(gè)過(guò)程中柬姚,原始的紋理被反復(fù)過(guò)濾成更小的圖像。
當(dāng)使用mipmapping最小化過(guò)濾器時(shí)庄涡,在實(shí)際呈現(xiàn)之前量承,原始紋理會(huì)被一組更小版本的紋理增強(qiáng)。紋理(在0級(jí))被向下采樣到原始區(qū)域的四分之一啼染,每個(gè)新的texel值通常計(jì)算為原始紋理中四個(gè)相鄰texel的平均值宴合。新的一級(jí)紋理有時(shí)被稱(chēng)為原始紋理的子紋理。遞歸地執(zhí)行縮減迹鹅,直到紋理的一個(gè)或兩個(gè)維度都等于一個(gè)texel卦洽。這個(gè)過(guò)程如圖6.15所示。作為一個(gè)整體的圖像集通常被稱(chēng)為mipmap鏈斜棚。
形成高質(zhì)量mipmap的兩個(gè)重要因素是良好的濾波和伽馬校正阀蒂。形成mipmap級(jí)別的常用方法是取每個(gè)2×2組texel,并對(duì)它們進(jìn)行平均弟蚀,得到mip texel值蚤霞。所使用的過(guò)濾器是一個(gè)盒子過(guò)濾器,可能是最差的過(guò)濾器之一义钉。這可能導(dǎo)致質(zhì)量很差昧绣,因?yàn)樗鼤?huì)不必要地模糊低頻,同時(shí)保留一些導(dǎo)致混疊的高頻[172]捶闸。最好使用高斯夜畴、Lanczos、Kaiser或類(lèi)似的過(guò)濾器;有很多解決這個(gè)問(wèn)題的快速删壮,免費(fèi)的源代碼[172,1592]贪绘,和一些api支持更好的濾波器內(nèi)置在GPU。在紋理的邊緣附近央碟,過(guò)濾時(shí)必須注意紋理是重復(fù)的還是單一的復(fù)制税灌。
對(duì)于非線(xiàn)性空間中編碼的紋理(如大多數(shù)顏色紋理),在過(guò)濾時(shí)忽略gamma校正將修改mipmap級(jí)別的感知亮度[173,607]亿虽。當(dāng)你離物體越遠(yuǎn)菱涤,使用未校正的mipmap,物體整體看起來(lái)就越暗经柴,對(duì)比度和細(xì)節(jié)也會(huì)受到影響狸窘。因此,將這些紋理從sRGB轉(zhuǎn)換為線(xiàn)性空間(第5.6節(jié))坯认,在該空間中執(zhí)行所有mipmap過(guò)濾,并將最終結(jié)果轉(zhuǎn)換回sRGB顏色空間進(jìn)行存儲(chǔ)是非常重要的。大多數(shù)api都支持sRGB紋理牛哺,因此可以在線(xiàn)性空間中正確生成mipmap并將結(jié)果存儲(chǔ)在sRGB中陋气。當(dāng)訪(fǎng)問(wèn)sRGB紋理時(shí),首先將它們的值轉(zhuǎn)換為線(xiàn)性空間引润,以便正確地執(zhí)行放大和縮小巩趁。
正如前面提到的,一些紋理與最終的陰影顏色有著基本的非線(xiàn)性關(guān)系淳附。雖然這在一般情況下會(huì)造成過(guò)濾問(wèn)題议慰,但是mipmap生成對(duì)這個(gè)問(wèn)題特別敏感,因?yàn)橐^(guò)濾成百上千個(gè)像素奴曙。為了獲得最佳結(jié)果别凹,通常需要使用專(zhuān)門(mén)的mipmap生成方法。這些方法詳見(jiàn)第9.13節(jié)洽糟。
訪(fǎng)問(wèn)這個(gè)結(jié)構(gòu)的基本過(guò)程炉菲,而紋理是直接的。屏幕像素在紋理本身上包圍一個(gè)區(qū)域坤溃。當(dāng)像素的區(qū)域投射到紋理上時(shí)(圖6.16)拍霜,它包含一個(gè)或多個(gè)紋理。使用像素的單元格邊界并不完全正確薪介,但是這里使用它是為了簡(jiǎn)化表示祠饺。單元格外的texel可以影響像素的顏色;5.4.1之前看到的部分。目標(biāo)是大致確定紋理對(duì)像素的影響程度汁政。有兩種常見(jiàn)的措施用來(lái)計(jì)算d(OpenGL稱(chēng)之為λ,也被稱(chēng)為紋理的細(xì)節(jié))道偷。一種是利用像素單元形成的較長(zhǎng)的四邊形邊緣來(lái)近似像素的覆蓋范圍[1889];另一個(gè)是將?u/?x,?v/?x烂完,?u/?y试疙,?v/?y這四個(gè)?的絕對(duì)值的最大值作為測(cè)量值[901,1411]。每個(gè)差分是紋理坐標(biāo)相對(duì)于屏幕軸的變化量的度量抠蚣。例如祝旷,?u/?x是一個(gè)像素的u紋理值沿屏幕x軸的變化量。有關(guān)這些方程的更多信息嘶窄,請(qǐng)參見(jiàn)Williams的原始文章[1889]或Flavell的文章[473]或Pharr的文章[1411]怀跛。McCormack等人[1160]討論了用最大絕對(duì)值法引入混疊,他們給出了一個(gè)替代公式柄冲。Ewins等[454]分析了幾種質(zhì)量相當(dāng)?shù)乃惴ǖ挠布杀尽?/p>
這些梯度值可用于使用shader Model 3.0或更新版本的像素著色器程序吻谋。由于它們是基于相鄰像素值之間的差異,因此在受動(dòng)態(tài)流控制影響的像素著色器部分(第3.8節(jié))是不可訪(fǎng)問(wèn)的现横。對(duì)于要在這樣的部分中執(zhí)行的紋理讀取(例如漓拾,在循環(huán)中)阁最,必須更早地計(jì)算導(dǎo)數(shù)。注意骇两,由于頂點(diǎn)著色器不能訪(fǎng)問(wèn)梯度信息速种,梯度或細(xì)節(jié)級(jí)別需要在頂點(diǎn)著色器本身計(jì)算,并在使用頂點(diǎn)紋理時(shí)提供給GPU低千。
計(jì)算坐標(biāo)d的目的是確定沿著mipmap的金字塔軸在哪里采樣配阵。參見(jiàn)圖6.15。目標(biāo)是像素與texel的比例至少為1:1示血,以實(shí)現(xiàn)奈奎斯特速率棋傍。這里的重要原則是,當(dāng)像素單元包含更多的紋理和d時(shí)难审,將訪(fǎng)問(wèn)一個(gè)更小瘫拣、更模糊的紋理版本。(u, v, d)三元組用于訪(fǎng)問(wèn)mipmap剔宪。值d類(lèi)似于紋理級(jí)別拂铡,但它不是一個(gè)整數(shù)值,而是級(jí)別之間距離的分?jǐn)?shù)值葱绒。對(duì)d位置上的紋理層和下的紋理層進(jìn)行采樣感帅。(u, v)位置用于從這兩個(gè)紋理級(jí)別中的每一個(gè)檢索bilinearly插值樣本。然后根據(jù)每個(gè)紋理層到d的距離地淀,對(duì)得到的樣本進(jìn)行線(xiàn)性插值失球。整個(gè)過(guò)程稱(chēng)為三線(xiàn)性插值,每像素執(zhí)行一次帮毁。
d坐標(biāo)上的一個(gè)用戶(hù)控件是細(xì)節(jié)偏差級(jí)別(LOD偏差)实苞。這是一個(gè)添加到d的值,因此它影響紋理的相對(duì)感知銳度烈疚。如果我們進(jìn)一步向上移動(dòng)金字塔開(kāi)始(增加d)黔牵,紋理將看起來(lái)更加模糊。對(duì)于任何給定的紋理爷肝,良好的LOD偏差都會(huì)隨著圖像類(lèi)型和使用方式的不同而變化猾浦。例如,一開(kāi)始有些模糊的圖像可能使用負(fù)偏置灯抛,而用于紋理處理的合成圖像過(guò)濾不良(別名)可能使用正偏置金赦。可以在像素著色器中為紋理整體或每個(gè)像素指定偏置对嚼。對(duì)于更精細(xì)的控制夹抗,用戶(hù)可以提供用于計(jì)算它的d坐標(biāo)或?qū)?shù)。
mipmapping的好處是纵竖,不需要分別對(duì)影響像素的所有texel進(jìn)行求和漠烧,而是訪(fǎng)問(wèn)和插值預(yù)組合的texel集杏愤。這個(gè)過(guò)程需要一定的時(shí)間,無(wú)論縮小多少沽甥。然而声邦,mipmapping有幾個(gè)缺陷[473]乏奥。一個(gè)主要問(wèn)題是過(guò)度模糊摆舟。假設(shè)一個(gè)像素單元在u方向上覆蓋了大量的texel,而在v方向上只覆蓋了texel邓了。這種情況通常發(fā)生在觀察者沿紋理表面幾乎是邊緣朝上看時(shí)恨诱。事實(shí)上,可能需要沿著紋理的一個(gè)軸進(jìn)行縮小骗炉,然后沿著另一個(gè)軸進(jìn)行放大照宝。訪(fǎng)問(wèn)mipmap的效果是檢索紋理上的正方形區(qū)域;檢索矩形區(qū)域是不可能的。為了避免混疊句葵,我們選擇紋理上像素單元的近似覆蓋率的最大度量厕鹃。這導(dǎo)致檢索到的樣本通常比較模糊。這種效果可以在圖6.14中的mipmap圖像中看到乍丈。向右移動(dòng)的線(xiàn)顯示出過(guò)度模糊剂碴。
總面積表 Summed-Area Table
避免過(guò)度模糊的另一種方法是求和區(qū)域表(sum-area table, SAT)[312]。要使用此方法轻专,首先創(chuàng)建一個(gè)與紋理大小相同的數(shù)組忆矛,但包含存儲(chǔ)的顏色的更多精度(例如,紅色请垛、綠色和藍(lán)色各16位或更多)催训。在這個(gè)數(shù)組的每個(gè)位置,必須計(jì)算和存儲(chǔ)由這個(gè)位置和texel(0,0)(原點(diǎn))組成的矩形中所有對(duì)應(yīng)紋理的texel的和宗收。在紋理處理過(guò)程中漫拭,像素單元在紋理上的投影被一個(gè)矩形綁定。然后訪(fǎng)問(wèn)sum-area表來(lái)確定這個(gè)矩形的平均顏色混稽,該顏色作為像素的紋理顏色傳遞回來(lái)采驻。使用圖6.17所示矩形的紋理坐標(biāo)計(jì)算平均值。使用式6.3所示公式:
這里荚坞,x和y是矩形的texel坐標(biāo)挑宠,s[x, y]是該texel的和面積值。這個(gè)方程的工作原理是從右上角到原點(diǎn)的整個(gè)面積的和颓影,然后減去A和B的面積減去相鄰角的貢獻(xiàn)各淀。面積C減去了兩次,所以它是由左下角加回來(lái)的诡挂。注意(xll, yll)是C區(qū)域的右上角碎浇,即临谱, (xll + 1, yll + 1)為邊界框的左下角。
使用求和區(qū)域表的結(jié)果如圖6.14所示奴璃。接近地平線(xiàn)的線(xiàn)在右邊邊緣更清晰悉默,但是中間的對(duì)角線(xiàn)交叉線(xiàn)仍然過(guò)于模糊。問(wèn)題是苟穆,當(dāng)一個(gè)紋理沿著它的對(duì)角線(xiàn)進(jìn)行觀察時(shí)抄课,會(huì)生成一個(gè)大的矩形,其中許多紋理都不位于正在計(jì)算的像素附近雳旅。例如跟磨,想象一個(gè)長(zhǎng)而薄的矩形,它代表像素單元的反投影攒盈,在圖6.17中對(duì)角線(xiàn)地橫過(guò)整個(gè)紋理抵拘。將返回整個(gè)紋理矩形的平均值,而不僅僅是像素單元內(nèi)的平均值型豁。
面積和表是所謂的各向異性濾波算法的一個(gè)例子[691]僵蛛。這種算法在非正方形的區(qū)域上檢索texel值。然而迎变,SAT能夠在主要水平和垂直方向上最有效地做到這一點(diǎn)充尉。還要注意,對(duì)于大小為16×16或更小的紋理氏豌,和區(qū)域表至少占用兩倍的內(nèi)存喉酌,對(duì)于較大的紋理,需要更高的精度泵喘。摘要面積表可以在現(xiàn)代gpu上實(shí)現(xiàn)泪电,它以合理的總體內(nèi)存成本提供更高的質(zhì)量[585]。改進(jìn)的濾波對(duì)高級(jí)渲染技術(shù)的質(zhì)量至關(guān)重要纪铺。例如相速,Hensley等人[718,719]提供了一種有效的實(shí)現(xiàn)方法,并展示了如何對(duì)面積進(jìn)行累加采樣來(lái)改善光澤反射鲜锚。其他使用面積采樣的算法可以通過(guò)SAT得到改進(jìn)突诬,如景深[585,719],陰影映射[988]芜繁,模糊反射[718]旺隙。
無(wú)約束各向異性過(guò)濾 Unconstrained Anisotropic Filtering
對(duì)于目前的圖形硬件,進(jìn)一步改進(jìn)紋理濾波最常用的方法是重用現(xiàn)有的mipmap硬件骏令。其基本思想是將像素單元反投影蔬捷,然后對(duì)紋理上的這個(gè)四邊形(quad)進(jìn)行多次采樣,并將這些采樣組合在一起。如上所述周拐,每個(gè)mipmap示例都有一個(gè)位置和一個(gè)與之相關(guān)的方形區(qū)域铡俐。該算法不是使用單一的mipmap樣本來(lái)近似這個(gè)四邊形的覆蓋范圍,而是使用幾個(gè)正方形來(lái)覆蓋這個(gè)四邊形妥粟。短邊的四分之一可以用來(lái)確定d(不像在mipmapping中审丘,通常使用較長(zhǎng)的邊);這使得每個(gè)mipmap樣本的平均面積更小(因此更不模糊)。四邊形的長(zhǎng)邊用于創(chuàng)建一條各向異性線(xiàn)勾给,平行于長(zhǎng)邊并穿過(guò)四邊形的中間滩报。當(dāng)各向異性的數(shù)量在1:1和2:1之間時(shí),沿著這條線(xiàn)取兩個(gè)樣本(見(jiàn)圖6.18)锦秒。在各向異性比例較高的情況下露泊,沿軸取的樣品較多。該方案允許各向異性線(xiàn)在任意方向運(yùn)行旅择,不受面積和表的限制。它也不需要比mipmap更多的紋理內(nèi)存侣姆,因?yàn)樗褂胢ipmap算法進(jìn)行采樣生真。各向異性濾波的一個(gè)例子如圖6.19所示。
這種沿軸采樣的想法最早是由Schilling等人通過(guò)他們的Texram動(dòng)態(tài)存儲(chǔ)設(shè)備提出的[1564]捺宗。Barkans描述了算法在Talisman系統(tǒng)中的使用[103]柱蟀。McCormack等人[1161]提出了一種類(lèi)似的系統(tǒng)媳溺,稱(chēng)為Feline进每。Texram的原始公式中夕土,各向異性軸anisotropic anix(也稱(chēng)為探針probes)上的樣品具有相同的權(quán)重芯侥。Talisman賦予軸兩端的兩個(gè)探針一半的權(quán)重澎埠。Feline使用高斯濾波器內(nèi)核核來(lái)對(duì)一組探針進(jìn)行加權(quán)祈噪。這些算法接近軟件采樣算法的高質(zhì)量雕擂,如橢圓加權(quán)平均(EWA)濾波器踊东,它將像素的影響區(qū)域轉(zhuǎn)化為對(duì)紋理的橢圓贰健,并通過(guò)濾波核對(duì)橢圓內(nèi)的紋理進(jìn)行加權(quán)[691]胞四。Mavridis和Papaioannou提出了幾種在GPU上使用著色器代碼實(shí)現(xiàn)EWA過(guò)濾的方法[1143]。
6.2.3 體積貼圖 Volume Textures
圖像紋理的一個(gè)直接擴(kuò)展是由(u, v,w)(或(s, t, r)值訪(fǎng)問(wèn)的三維圖像數(shù)據(jù)伶椿。例如辜伟,醫(yī)學(xué)成像數(shù)據(jù)可以生成一個(gè)三維網(wǎng)格;通過(guò)在網(wǎng)格中移動(dòng)一個(gè)多邊形,可以查看這些數(shù)據(jù)的二維切片脊另。一個(gè)相關(guān)的想法是用這種形式表示體積光导狡。在一個(gè)表面上的一個(gè)點(diǎn)上的照明是通過(guò)找到它在這個(gè)體積內(nèi)的位置的值,結(jié)合光的方向來(lái)發(fā)現(xiàn)的偎痛。
大多數(shù)gpu支持卷紋理的mipmapping旱捧。由于在體紋理的單個(gè)mipmap級(jí)別內(nèi)的過(guò)濾涉及到三線(xiàn)性插值,因此在mipmap級(jí)別之間的過(guò)濾需要四線(xiàn)性插值看彼。由于這涉及到對(duì)16個(gè)紋理的結(jié)果進(jìn)行平均廊佩,可能會(huì)產(chǎn)生精度問(wèn)題囚聚,可以通過(guò)使用更高精度的體紋理來(lái)解決。Sigg和Hadwiger[1638]討論了這個(gè)問(wèn)題和其他與體紋理相關(guān)的問(wèn)題标锄,并提供了執(zhí)行過(guò)濾和其他操作的有效方法顽铸。
盡管卷紋理有更高的存儲(chǔ)要求,而且過(guò)濾成本更高料皇,但它們確實(shí)有一些獨(dú)特的優(yōu)勢(shì)谓松。由于三維位置可以直接用作紋理坐標(biāo),因此可以跳過(guò)為三維網(wǎng)格尋找良好的二維參數(shù)化的復(fù)雜過(guò)程践剂。這避免了通常使用二維參數(shù)化出現(xiàn)的失真和接縫問(wèn)題鬼譬。體紋理還可以用來(lái)表示木材或大理石等材料的體結(jié)構(gòu)。模型紋理與這樣的紋理將出現(xiàn)從這種材料雕刻逊脯。
使用體紋理進(jìn)行表面紋理是非常低效的优质,因?yàn)榻^大多數(shù)采樣都沒(méi)有使用。Benson和Davis[133]以及DeBry等[334]討論了在稀疏八叉樹(shù)結(jié)構(gòu)中存儲(chǔ)紋理數(shù)據(jù)的問(wèn)題军洼。該方案非常適合交互式三維繪畫(huà)系統(tǒng)巩螃,因?yàn)榍嬖趧?chuàng)建時(shí)不需要指定明確的紋理坐標(biāo),并且八叉樹(shù)可以將紋理細(xì)節(jié)控制在任何需要的水平匕争。Lefebvre等[1017]討論了在現(xiàn)代GPU上實(shí)現(xiàn)八叉樹(shù)紋理的細(xì)節(jié)避乏。Lefebvre和Hoppe[1018]討論了一種將稀疏體數(shù)據(jù)打包成明顯更小的紋理的方法。
6.2.4 Cube Maps
另一種類(lèi)型的紋理是Cube Texture或Cube Map甘桑,它有六個(gè)方形紋理拍皮,每個(gè)都與一個(gè)立方體的一個(gè)面相關(guān)聯(lián)。使用一個(gè)三分量紋理坐標(biāo)矢量訪(fǎng)問(wèn)一個(gè)立方體映射跑杭,該矢量指定從立方體中心向外的射線(xiàn)的方向铆帽。射線(xiàn)與立方體相交的點(diǎn)如下所示。大小最大的紋理坐標(biāo)選擇對(duì)應(yīng)的面(例如艘蹋,向量(-3.2,5.1锄贼,-8.4)選擇-z面)。其余兩個(gè)坐標(biāo)除以最大星等坐標(biāo)的絕對(duì)值女阀,即8.4點(diǎn)≌纾現(xiàn)在它們的范圍從- 1到1,并且簡(jiǎn)單地重映射到[0,1]以便計(jì)算紋理坐標(biāo)浸策。例如,坐標(biāo)(?3.2,5.1)映射到((?3.2/8.4 + 1)/ 2,(5.1/8.4 + 1)/ 2) ≈ (0.31,0.80)冯键。立方體映射對(duì)于表示方向函數(shù)的值很有用;它們最常用于環(huán)境映射(第10.4.3節(jié))。
6.2.5 紋理表示 Texture Representation
在應(yīng)用程序中處理許多紋理時(shí)庸汗,有幾種方法可以提高性能惫确。紋理壓縮在第6.2.6節(jié)中進(jìn)行了描述,而本節(jié)的重點(diǎn)是紋理圖集(texture atlases)、紋理數(shù)組(texture arrays)和無(wú)綁定紋理(bindless textures)改化,所有這些都是為了避免在呈現(xiàn)時(shí)更改紋理的成本掩蛤。在19.10.1和19.10.2節(jié)中,描述了紋理流和代碼轉(zhuǎn)換陈肛。
為了能夠?yàn)镚PU批量處理盡可能多的工作揍鸟,通常傾向于盡可能少地更改狀態(tài)(第18.4.2節(jié))。為此句旱,可以將多個(gè)圖像放入一個(gè)更大的紋理中阳藻,稱(chēng)為紋理圖集。這在圖6.20的左邊進(jìn)行了說(shuō)明谈撒。注意腥泥,子紋理的形狀可以是任意的,如圖6.6所示啃匿。子紋理布局地集的優(yōu)化由N¨oll和Stricker[1286]描述蛔外。還需要注意mipmap的生成和訪(fǎng)問(wèn),因?yàn)閙ipmap的上層可能包含幾個(gè)獨(dú)立的立宜、不相關(guān)的形狀冒萄。Manson和Schaefer[1119]提出了一種考慮曲面參數(shù)化的優(yōu)化mipmap創(chuàng)建方法,該方法可以產(chǎn)生更好的結(jié)果橙数。Burley和Lacewell[213]提出了一種叫做Ptex的系統(tǒng),在這個(gè)系統(tǒng)中帅戒,細(xì)分表面上的每個(gè)四邊形都有自己的小紋理灯帮。這樣做的好處是避免了在網(wǎng)格上分配唯一的紋理坐標(biāo),并且在紋理圖集的斷開(kāi)部分的接縫上沒(méi)有瑕疵逻住。為了能夠跨四元組過(guò)濾钟哥,Ptex使用鄰接數(shù)據(jù)結(jié)構(gòu)。當(dāng)最初的目標(biāo)是渲染時(shí)瞎访,Hillesland[746]介紹了壓縮的Ptex腻贰,它將每個(gè)面的子紋理放入一個(gè)紋理圖集中,并使用相鄰面的填充來(lái)避免過(guò)濾時(shí)的間隔性扒秸。Yuksel[1955]提出了網(wǎng)格顏色紋理播演,它改進(jìn)了Ptex。Toth[1780]為類(lèi)ptex系統(tǒng)提供了高質(zhì)量的跨面過(guò)濾伴奥,它實(shí)現(xiàn)了一種方法写烤,如果過(guò)濾錐不在[0,1]2的范圍內(nèi),則丟棄過(guò)濾錐拾徙。
使用圖集的一個(gè)困難是Wrap/Repeat和Mirror模式洲炊,這不會(huì)正確地影響子紋理,但只會(huì)影響整個(gè)紋理。另一個(gè)問(wèn)題可能發(fā)生在為一個(gè)圖集生成mipmaps時(shí)暂衡,其中一個(gè)子紋理可能滲入另一個(gè)子紋理询微。然而,在將每個(gè)子紋理放入一個(gè)大型紋理圖集之前狂巢,分別為每個(gè)子紋理生成mipmap層次結(jié)構(gòu)撑毛,并對(duì)子紋理使用2的冪次分辨率,可以避免這種情況[1293]隧膘。
解決這些問(wèn)題的一個(gè)更簡(jiǎn)單的方法是使用稱(chēng)為紋理數(shù)組的API構(gòu)造代态,它完全避免了mipmapping和重復(fù)模式的任何問(wèn)題[452]。參見(jiàn)圖6.20的右邊部分疹吃。紋理數(shù)組中的所有子紋理都需要具有相同的維度蹦疑、格式、mipmap層次結(jié)構(gòu)和MSAA設(shè)置萨驶。和紋理圖集一樣歉摧,設(shè)置一個(gè)紋理數(shù)組只需要執(zhí)行一次,然后可以使用著色器中的索引訪(fǎng)問(wèn)任何數(shù)組元素腔呜。這比綁定每個(gè)子紋理快5倍[452]叁温。
一個(gè)可以幫助避免狀態(tài)更改成本的特性是對(duì)無(wú)綁定紋理的API支持[1407]。如果沒(méi)有無(wú)綁定紋理核畴,則使用API將紋理綁定到特定的紋理單元膝但。一個(gè)問(wèn)題是紋理單元數(shù)量的上限,這使程序員的事情變得復(fù)雜谤草。驅(qū)動(dòng)程序確保紋理駐留在GPU端跟束。對(duì)于無(wú)綁定的紋理,沒(méi)有紋理數(shù)量的上限丑孩,因?yàn)槊總€(gè)紋理僅由64位指針(有時(shí)稱(chēng)為句柄)與其數(shù)據(jù)結(jié)構(gòu)關(guān)聯(lián)冀宴。這些句柄可以通過(guò)許多不同的方式訪(fǎng)問(wèn),例如温学,通過(guò)uniforms略贮,通過(guò)varying data,從其他紋理仗岖,或從著色器存儲(chǔ)緩沖對(duì)象(SSBO)逃延。應(yīng)用程序需要確保紋理駐留在GPU端。無(wú)綁定紋理避免了驅(qū)動(dòng)程序中的任何類(lèi)型的綁定成本箩帚,這使得渲染速度更快真友。
6.2.6 貼圖壓縮 Texture Compression
一種直接解決內(nèi)存和帶寬問(wèn)題以及緩存問(wèn)題的解決方案是固定速率紋理壓縮[127]。通過(guò)GPU實(shí)時(shí)解碼壓縮紋理紧帕,紋理可以占用更少的紋理內(nèi)存盔然,從而增加有效的緩存大小桅打。至少同樣重要的是,這樣的紋理使用起來(lái)更高效愈案,因?yàn)樗鼈冊(cè)谠L(fǎng)問(wèn)時(shí)消耗的內(nèi)存帶寬更少挺尾。一個(gè)相關(guān)但不同的用例是為了提供更大的紋理而添加壓縮。例如站绪,在5122分辨率下遭铺,每個(gè)texel使用3個(gè)字節(jié)的非壓縮紋理將占用768 kB。使用紋理壓縮恢准,壓縮比為6:1,10242紋理只占用512 kB魂挂。
圖像文件格式(如JPEG和PNG)中使用了多種圖像壓縮方法,但是在硬件中實(shí)現(xiàn)對(duì)這些方法的解碼非常昂貴(關(guān)于紋理轉(zhuǎn)碼的信息馁筐,請(qǐng)參閱19.10.1節(jié))涂召。S3開(kāi)發(fā)了一種稱(chēng)為S3紋理壓縮(S3TC)的方案[1524],該方案被選為DirectX的標(biāo)準(zhǔn)敏沉,稱(chēng)為dxtcin DirectX 10果正,稱(chēng)為BC(塊壓縮)。此外盟迟,它是OpenGL中事實(shí)上的標(biāo)準(zhǔn)秋泳,因?yàn)閹缀跛術(shù)pu都支持它。它的優(yōu)點(diǎn)是創(chuàng)建一個(gè)大小固定攒菠、獨(dú)立編碼的壓縮圖像迫皱,并且解碼簡(jiǎn)單(因此也快速)。圖像的每個(gè)壓縮部分都可以獨(dú)立于其他部分處理辖众。沒(méi)有共享查找表或其他依賴(lài)項(xiàng)舍杜,這簡(jiǎn)化了解碼。
DXTC/BC壓縮方案有七種變體赵辕,它們具有一些共同的特性。編碼是在4×4的texel塊上完成的概龄,也稱(chēng)為tile还惠。每個(gè)塊分別編碼。編碼基于插值私杜。對(duì)于每個(gè)編碼的量蚕键,存儲(chǔ)兩個(gè)參考值(例如,顏色)衰粹。為塊中的16個(gè)texel中的每個(gè)保存一個(gè)插值因子锣光。它在兩個(gè)參考值之間的直線(xiàn)上選擇一個(gè)值,例如铝耻,一個(gè)顏色等于或從兩個(gè)存儲(chǔ)的顏色中插入誊爹。壓縮來(lái)自于僅存儲(chǔ)兩種顏色以及每個(gè)像素的短索引值蹬刷。
在表6.1中總結(jié)了這7種變體之間的精確編碼。注意频丘,“DXT”表示DirectX 9中的名稱(chēng)办成,“BC”表示DirectX 10及以上的名稱(chēng)。從表中可以看出搂漠,BC1有兩個(gè)16位參考RGB值(5位紅色迂卢,6位綠色,5位藍(lán)色)桐汤,每個(gè)texel都有一個(gè)2位插值因子而克,可以從一個(gè)參考值或兩個(gè)中間值中選擇。與未壓縮的24位RGB紋理相比怔毛,這表示紋理壓縮比為6:1员萍。BC2以與BC1相同的方式編碼顏色,但是每個(gè)texel (bpt)為量子化(raw) alpha添加4位馆截。對(duì)于BC3充活,每個(gè)塊都以與DXT1塊相同的方式編碼RGB數(shù)據(jù)。此外蜡娶,alpha數(shù)據(jù)使用兩個(gè)8位參考值和一個(gè)3位插值因子進(jìn)行編碼混卵。每個(gè)texel可以選擇一個(gè)參考alpha值或六個(gè)中間值中的一個(gè)。BC4有一個(gè)通道窖张,在BC3中編碼為alpha幕随。BC5包含兩個(gè)通道,其中每個(gè)通道編碼為BC3宿接。
BC6H用于高動(dòng)態(tài)范圍(HDR)紋理赘淮,其中每個(gè)texel最初在每個(gè)R、G和B通道上都有16位浮點(diǎn)值睦霎。這種模式使用16個(gè)字節(jié)梢卸,結(jié)果是8個(gè)bpt。它為單行提供一種模式(類(lèi)似于上面的技術(shù))副女,為兩行提供另一種模式蛤高,其中每個(gè)塊可以從一小組分區(qū)中選擇。兩種參考顏色也可以進(jìn)行delta編碼以獲得更高的精度碑幅,并且根據(jù)使用的模式也可以有不同的精度戴陡。在BC7中,每個(gè)塊可以有1到3行代碼沟涨,并存儲(chǔ)8個(gè)bpt恤批。目標(biāo)是高質(zhì)量的紋理壓縮8位RGB和RGBA紋理。它與BC6H共享許多屬性裹赴,但是是LDR紋理的格式喜庞,而B(niǎo)C6H是HDR的格式诀浪。注意,在OpenGL中赋荆,BC6H和BC7分別稱(chēng)為BPTC FLOAT和BPTC笋妥。這些壓縮技術(shù)可以應(yīng)用于立方體或體紋理,以及二維紋理窄潭。
這些壓縮方案的主要缺點(diǎn)是它們是有損的春宣。也就是說(shuō),通常無(wú)法從壓縮版本中檢索原始圖像嫉你。在BC1-BC5中月帝,只有4或8個(gè)插值值用于表示16個(gè)像素。如果一個(gè)tile中有大量不同的值幽污,就會(huì)有一些損失嚷辅。在實(shí)踐中,如果使用正確距误,這些壓縮方案通臭じ悖可以提供可接受的圖像保真度。
BC1-BC5的問(wèn)題之一是准潭,用于塊的所有顏色都位于RGB空間中的直線(xiàn)上趁俊。例如,紅色刑然、綠色和藍(lán)色不能在一個(gè)塊中表示寺擂。BC6H和BC7支持更多的線(xiàn)路,因此可以提供更高的質(zhì)量泼掠。
對(duì)于OpenGL ES怔软,選擇了另一種壓縮算法Ericsson texture compression (ETC)[1714]來(lái)包含在API中。該方案與S3TC一樣具有解碼速度快择镇、隨機(jī)存取挡逼、無(wú)間接查找、速率固定等特點(diǎn)腻豌。它將一個(gè)4×4的文本塊編碼為64位挚瘟,即,每個(gè)texel使用4位饲梭。基本思想如圖6.21所示焰檩。每個(gè)2×4塊(或4×2塊憔涉,取決于哪個(gè)塊質(zhì)量最好)存儲(chǔ)一個(gè)基本顏色。每個(gè)塊還從一個(gè)小型靜態(tài)查找表中選擇一組四個(gè)常量析苫,塊中的每個(gè)texel都可以選擇添加該表中的一個(gè)值兜叨。這將修改每個(gè)像素的亮度穿扳。圖像質(zhì)量與DXTC相當(dāng)。
在ETC2[1715]中国旷,OpenGL ES 3.0中包含了未使用的位組合矛物,為原有的ETC算法添加了更多的模式。未使用的位組合是壓縮表示(例如跪但,64位)履羞,它解壓縮為與另一個(gè)壓縮表示相同的圖像。例如屡久,在BC1中忆首,將兩個(gè)引用顏色設(shè)置為相同是沒(méi)有用的,因?yàn)檫@將表示一個(gè)常量顏色塊被环,而只要一個(gè)引用顏色包含該常量顏色糙及,就可以得到該常量顏色塊。在ETC中筛欢,一種顏色也可以從帶有符號(hào)號(hào)的第一種顏色編碼為delta浸锨,因此計(jì)算可以溢出或下溢。這種情況被用來(lái)信號(hào)其他壓縮模式版姑。ETC2增加了兩種新的模式柱搜,每種模式有四種顏色,每種顏色的派生方式不同漠酿,最后一種模式是RGB空間中的一個(gè)平面冯凹,用于處理平滑的轉(zhuǎn)換。Ericsson alpha compression (EAC)[1868]壓縮只有一個(gè)組件的圖像(e.g, alpha).這種壓縮類(lèi)似于基本ETC壓縮炒嘲,但只針對(duì)一個(gè)組件宇姚,生成的圖像每個(gè)texel存儲(chǔ)4位。它可以選擇與ETC2結(jié)合使用夫凸,此外浑劳,還可以使用兩個(gè)EAC通道來(lái)壓縮法線(xiàn)(更多內(nèi)容見(jiàn)下面的主題)。所有ETC1夭拌、ETC2和EAC都是OpenGL 4.0核心profile魔熏、OpenGL ES 3.0、Vulkan和Metal的一部分鸽扁。
壓縮法線(xiàn)貼圖(在第6.7.2節(jié)中討論)需要注意蒜绽。為RGB顏色設(shè)計(jì)的壓縮格式通常不適用于普通的xyz數(shù)據(jù)。大多數(shù)方法都利用了法線(xiàn)已知為單位長(zhǎng)度這一事實(shí)桶现,并進(jìn)一步假設(shè)其z分量為正(對(duì)于切線(xiàn)空間法線(xiàn)來(lái)說(shuō)躲雅,這是一個(gè)合理的假設(shè))。這只允許存儲(chǔ)法線(xiàn)的x和y分量骡和。z分量是動(dòng)態(tài)地派生出來(lái)的:
這本身會(huì)導(dǎo)致適度的壓縮相赁,因?yàn)橹淮鎯?chǔ)兩個(gè)組件相寇,而不是三個(gè)。由于大多數(shù)gpu本身并不支持三組件紋理钮科,這也避免了浪費(fèi)組件的可能性(或者必須在第四個(gè)組件中打包另一個(gè)數(shù)量)唤衫。進(jìn)一步的壓縮通常通過(guò)以BC5 / 3Dc-format的紋理存儲(chǔ)x和y組件來(lái)實(shí)現(xiàn)。參見(jiàn)圖6.22绵脯。由于每個(gè)塊的參考值限定了最小和最大的x和y分量值佳励,因此可以將它們視為在xy平面上定義了一個(gè)邊界框。3位插值因子允許在每個(gè)軸上選擇8個(gè)值桨嫁,因此邊界框被劃分為一個(gè)8×8的可能法線(xiàn)網(wǎng)格植兰。或者璃吧,可以使用EAC的兩個(gè)通道(用于x和y)楣导,然后計(jì)算上面定義的z。
在不支持BC5/3Dc或EAC格式的硬件上畜挨,一個(gè)常見(jiàn)的備用方法[1227]是使用dxt5格式紋理筒繁,并將兩個(gè)組件存儲(chǔ)為綠色和alpha組件(因?yàn)檫@些組件的存儲(chǔ)精度最高)。另外兩個(gè)組件未使用巴元。
PVRTC[465]是一種紋理壓縮格式毡咏,可以在Imagination Technologies的硬件PowerVR上使用,它最廣泛的應(yīng)用是在iphone和ipad上逮刨。它為每個(gè)texel提供了2位和4位的方案呕缭,并壓縮了4×4個(gè)texel的塊。其關(guān)鍵思想是提供圖像的兩個(gè)低頻(平滑)信號(hào)修己,這兩個(gè)信號(hào)是通過(guò)相鄰的texel數(shù)據(jù)塊和插值得到的恢总。然后,使用每個(gè)texel 1或2位元對(duì)圖像上的兩個(gè)信號(hào)進(jìn)行插值睬愤。
自適應(yīng)可伸縮紋理壓縮(Adaptive scalable texture compression, ASTC)[1302]的不同之處在于片仿,它將一個(gè)n×m的紋理塊壓縮成128位。塊大小從4×4到12×12不等尤辱,這導(dǎo)致了不同的比特率砂豌,最低為0.89位/ texel,最高為8位/ texel光督。ASTC為緊湊索引表示使用了多種技巧阳距,每個(gè)塊可以選擇行數(shù)和端點(diǎn)編碼。此外结借,ASTC可以處理每個(gè)紋理1-4個(gè)通道娄涩,以及LDR和HDR紋理。ASTC是OpenGL ES 3.2及更高版本的一部分。
上面給出的所有紋理壓縮方案都是有損的蓄拣,當(dāng)壓縮一個(gè)紋理時(shí),可以在這個(gè)過(guò)程中花費(fèi)不同的時(shí)間努隙。在壓縮上花費(fèi)幾秒鐘甚至幾分鐘球恤,就可以獲得更高的質(zhì)量;因此,這通常是作為離線(xiàn)預(yù)處理完成的荸镊,并存儲(chǔ)起來(lái)供以后使用咽斧。或者躬存,你可以只花幾毫秒的時(shí)間张惹,因此質(zhì)量較低,但紋理可以被壓縮在接近實(shí)時(shí)和立即使用岭洲。一個(gè)例子是skybox(第13.3節(jié))宛逗,它大約每隔一秒就會(huì)重新生成一次,此時(shí)云可能已經(jīng)輕微移動(dòng)了盾剩。解壓非忱准ぃ快,因?yàn)樗鞘褂霉潭üδ苡布瓿傻母嫠健_@種差異稱(chēng)為數(shù)據(jù)壓縮不對(duì)稱(chēng)屎暇,在這種情況下,壓縮可以而且確實(shí)需要比解壓縮長(zhǎng)得多的時(shí)間驻粟。
Kaplanyan[856]提出了幾種提高壓縮紋理質(zhì)量的方法根悼。對(duì)于包含顏色和法線(xiàn)貼圖的紋理,建議使用每個(gè)組件16位元來(lái)創(chuàng)建貼圖蜀撑。對(duì)于顏色紋理挤巡,然后執(zhí)行直方圖重新標(biāo)準(zhǔn)化(對(duì)這16位),然后在著色器中使用比例和偏置常數(shù)(每個(gè)紋理)反轉(zhuǎn)直方圖的效果屯掖。直方圖歸一化是將圖像中使用的值分散到整個(gè)范圍內(nèi)的一種技術(shù)玄柏,是一種有效的對(duì)比度增強(qiáng)方法。每個(gè)組件使用16位元贴铜,可以確保直方圖在重新標(biāo)準(zhǔn)化之后沒(méi)有未使用的槽粪摘,這減少了許多紋理壓縮方案可能引入的帶狀偽跡。如圖6.23所示绍坝。此外徘意,Kaplanyan建議,如果75%的像素在116/255以上轩褐,那么紋理使用線(xiàn)性顏色空間椎咧,否則將紋理存儲(chǔ)在sRGB中。對(duì)于法線(xiàn)貼圖,他還指出BC5/3Dc經(jīng)常獨(dú)立于y壓縮x勤讽,這意味著并不總是能找到最好的法線(xiàn)蟋座。相反,他建議對(duì)法線(xiàn)使用以下誤差度量:
其中n為原始法線(xiàn)脚牍,nc為相同的法線(xiàn)壓縮后再解壓縮向臀。
需要注意的是,也可以在不同的顏色空間壓縮紋理诸狭,這可以用來(lái)加快紋理壓縮券膀。常用的變換是RGB→YCoCg [1112]:
其中Y是亮度項(xiàng)Co和Cg是色度項(xiàng)。逆變換也很便宜:
這相當(dāng)于增加了一些內(nèi)容驯遇。這兩個(gè)變換是線(xiàn)性的芹彬,從方程6.6可以看出,它是一個(gè)矩陣-向量乘法叉庐,它本身是線(xiàn)性的(見(jiàn)方程4.1和4.2)舒帮。這很重要,因?yàn)榭梢源鎯?chǔ)YCoCg眨唬,而不是在紋理中存儲(chǔ)RGB;紋理硬件仍然可以在YCoCg空間中執(zhí)行過(guò)濾会前,然后像素著色器可以根據(jù)需要轉(zhuǎn)換回RGB。應(yīng)該注意的是匾竿,這種轉(zhuǎn)換本身是有損的瓦宜,這可能無(wú)關(guān)緊要。
還有一種可逆的RGB→YCoCg變換岭妖,總結(jié)為:
這意味著可以在24位RGB顏色和相應(yīng)的YCoCg表示之間來(lái)回轉(zhuǎn)換临庇,而不會(huì)有任何損失。需要注意的是昵慌,如果RGB中的每個(gè)分量都有n位元假夺,那么Co和Cg都有n + 1位元,以保證可逆變換;不過(guò)Y只需要n位斋攀。Van Waveren Casta?no[1852]使用有損YCoCg變換來(lái)實(shí)現(xiàn)快速壓縮DXT5 / BC3 CPU或GPU已卷。它們將Y存儲(chǔ)在alpha通道中(因?yàn)樗木茸罡?,而Co和Cg存儲(chǔ)在RGB的前兩個(gè)組件中淳蔼。壓縮變得很快侧蘸,因?yàn)閅是單獨(dú)存儲(chǔ)和壓縮的。對(duì)于Co-和cg組件鹉梨,他們找到一個(gè)二維邊界框并選擇產(chǎn)生最佳結(jié)果的框?qū)蔷€(xiàn)讳癌。注意,對(duì)于在CPU上動(dòng)態(tài)創(chuàng)建的紋理存皂,最好也在CPU上進(jìn)行紋理壓縮晌坤。當(dāng)紋理通過(guò)GPU渲染創(chuàng)建時(shí),通常最好也在GPU上進(jìn)行紋理壓縮。YCoCg變換和其他亮度-色度變換常用于圖像壓縮骤菠,其中色度分量的平均值超過(guò)2×2像素它改。這樣可以減少50%的存儲(chǔ)空間,而且通常效果很好商乎,因?yàn)樯茸兓容^慢搔课。Lee-Steere和Harmon[1015]進(jìn)一步將其轉(zhuǎn)換為色調(diào)飽和度值(hue- satur- value, HSV)删铃,在x和y中將色調(diào)和飽和度的采樣值降低4倍入问,并將值存儲(chǔ)為單個(gè)通道DXT1紋理融涣。Van Waveren andCasta?no也描述了快速壓縮法線(xiàn)貼圖[1853]的方法。
Griffin和Olano[601]的研究表明崩瓤,當(dāng)多個(gè)紋理應(yīng)用于具有復(fù)雜陰影模型的幾何模型時(shí),紋理的質(zhì)量往往很低踩官,沒(méi)有任何可感知的差異却桶。因此,根據(jù)用例蔗牡,降低質(zhì)量是可以接受的颖系。Fauconneau[463]提出了一種針對(duì)directx11紋理壓縮格式的SIMD實(shí)現(xiàn)。
6.3 程序化貼圖 Procedural Texturing
給定紋理空間位置辩越,執(zhí)行圖像查找是生成紋理值的一種方法嘁扼。另一種方法是對(duì)函數(shù)求值,從而定義過(guò)程紋理黔攒。
雖然過(guò)程紋理通常用于離線(xiàn)渲染應(yīng)用程序趁啸,但圖像紋理在實(shí)時(shí)渲染中更為常見(jiàn)。這是因?yàn)楝F(xiàn)代gpu中圖像紋理硬件的極高效率督惰,可以在一秒鐘內(nèi)執(zhí)行數(shù)十億次紋理訪(fǎng)問(wèn)不傅。然而,GPU架構(gòu)正在向更便宜的計(jì)算和(相對(duì))更昂貴的內(nèi)存訪(fǎng)問(wèn)發(fā)展赏胚。這些趨勢(shì)使得過(guò)程紋理在實(shí)時(shí)應(yīng)用程序中得到了更大的應(yīng)用访娶。
考慮到體圖像紋理的高存儲(chǔ)成本,體紋理是一個(gè)特別有吸引力的程序紋理應(yīng)用程序觉阅。這種紋理可以通過(guò)多種技術(shù)合成崖疤。最常見(jiàn)的一種方法是使用一個(gè)或多個(gè)噪聲函數(shù)來(lái)生成值[407,1370,1371,1372]。參見(jiàn)圖6.24留拾。噪聲函數(shù)通常以連續(xù)的2次冪頻率采樣戳晌,稱(chēng)為八度(octaves)。每個(gè)八度都有一個(gè)權(quán)值痴柔,通常隨著頻率的增加而下降沦偎,這些加權(quán)樣本的和稱(chēng)為湍流函數(shù)(turbulence function)。
由于計(jì)算噪聲函數(shù)的代價(jià)較大,三維陣列中的格點(diǎn)通常是預(yù)先計(jì)算好的豪嚎,用來(lái)插值紋理值搔驼。使用顏色緩沖混合快速生成這些數(shù)組的方法有很多[1192]。Perlin[1373]提出了一種快速侈询、實(shí)用的采樣該噪聲函數(shù)的方法舌涨,并展示了一些用途。Olano[1319]提供了噪聲生成算法扔字,允許在存儲(chǔ)紋理和執(zhí)行計(jì)算之間進(jìn)行權(quán)衡囊嘉。McEwan等人[1168]開(kāi)發(fā)了不需要任何查找就可以計(jì)算著色器中的經(jīng)典噪聲和單純?cè)肼暤姆椒ǎ⑻峁┝嗽创a革为。Parberry[1353]使用動(dòng)態(tài)規(guī)劃將計(jì)算分?jǐn)偟綆讉€(gè)像素上扭粱,以加速噪聲計(jì)算。Green[587]提供了一種更高質(zhì)量的方法震檩,但它更適合于近交互應(yīng)用程序琢蛤,因?yàn)樗褂?0像素著色器指令進(jìn)行一次查找∨茁玻可以對(duì)Perlin[1370, 1371, 1372]提出的原始噪聲函數(shù)進(jìn)行改進(jìn)博其。Cook和DeRose[290]提出了另一種表示方法,稱(chēng)為小波噪聲(wavelet noise)迂猴,它避免了混疊問(wèn)題慕淡,只增加了很小的評(píng)估成本。Liu等[1054]使用多種噪聲函數(shù)來(lái)模擬不同的木材紋理和表面飾面错忱。我們還推薦Lagae等人[956]關(guān)于這一主題的最新報(bào)告儡率。
其他的程序方法是可能的。例如以清,通過(guò)測(cè)量從每個(gè)位置到散布在空間中的一組“特征點(diǎn)”的距離儿普,就形成了一個(gè)細(xì)胞紋理。以不同的方式映射結(jié)果的最近距離掷倔,例如眉孩,改變顏色或正常陰影,創(chuàng)建看起來(lái)像細(xì)胞勒葱、石板浪汪、蜥蜴皮膚和其他自然紋理的模式。Griffiths[602]討論了如何高效地找到最近的鄰居并在GPU上生成細(xì)胞紋理凛虽。
另一種類(lèi)型的程序紋理是物理模擬的結(jié)果死遭,或者是一些其他交互過(guò)程的結(jié)果,例如水波或擴(kuò)展裂縫凯旋。在這種情況下呀潭,過(guò)程紋理可以有效地在動(dòng)態(tài)條件下產(chǎn)生無(wú)限的變化钉迷。
在生成過(guò)程性的二維紋理時(shí),參數(shù)化問(wèn)題可能比創(chuàng)建紋理帶來(lái)更大的困難钠署,在創(chuàng)建紋理時(shí)糠聪,可以手動(dòng)修改或修改拉伸或接縫瑕疵。一種解決方案是通過(guò)直接在表面合成紋理來(lái)完全避免參數(shù)化谐鼎。在復(fù)雜表面上進(jìn)行這種操作在技術(shù)上具有挑戰(zhàn)性舰蟆,是一個(gè)活躍的研究領(lǐng)域。有關(guān)這一領(lǐng)域的概述狸棍,請(qǐng)參見(jiàn)Wei等人[1861]身害。
反走樣過(guò)程紋理比反走樣圖像紋理既困難又容易。一方面草戈,像mipmapping這樣的預(yù)計(jì)算方法是不可用的题造,這給程序員帶來(lái)了負(fù)擔(dān)。另一方面猾瘸,過(guò)程紋理作者擁有關(guān)于紋理內(nèi)容的“內(nèi)部信息”,因此可以對(duì)其進(jìn)行調(diào)整以避免混疊丢习。這對(duì)于通過(guò)合并多個(gè)噪聲函數(shù)創(chuàng)建的過(guò)程紋理尤其正確牵触。每個(gè)噪聲函數(shù)的頻率都是已知的,因此任何可能導(dǎo)致混疊的頻率都可以被丟棄咐低,這實(shí)際上降低了計(jì)算的成本揽思。有各種各樣的技術(shù)來(lái)消除其他類(lèi)型的過(guò)程紋理的混疊[407,605,1392,1512]。Dorn等[371]討論了以前的工作见擦,并提出了一些重新構(gòu)造紋理函數(shù)以避免高頻的過(guò)程钉汗,即,以限制帶寬鲤屡。
6.4 紋理動(dòng)畫(huà) Texture Animation
應(yīng)用于表面的圖像不一定是靜態(tài)的损痰。例如,視頻源可以用作幀與幀之間變化的紋理酒来。
紋理坐標(biāo)也不需要是靜態(tài)的卢未。應(yīng)用程序設(shè)計(jì)器可以顯式地在幀與幀之間更改紋理坐標(biāo),或者在網(wǎng)格的數(shù)據(jù)本身中更改堰汉,或者通過(guò)在頂點(diǎn)著色器或像素著色器中應(yīng)用的函數(shù)更改辽社。想象一下,一個(gè)瀑布已經(jīng)被建模翘鸭,并且它已經(jīng)被一個(gè)看起來(lái)像落水的圖像紋理化了滴铅。假設(shè)v坐標(biāo)是流體的方向。要使水運(yùn)動(dòng)就乓,必須從每一幀的v坐標(biāo)中減去一個(gè)量汉匙。從紋理坐標(biāo)中減去會(huì)使紋理本身看起來(lái)向前移動(dòng)拱烁。
通過(guò)將矩陣應(yīng)用到紋理坐標(biāo),可以創(chuàng)建更精細(xì)的效果盹兢。除了平移邻梆,這還允許線(xiàn)性變換,如縮放绎秒、旋轉(zhuǎn)和剪切[1192,1904]浦妄、圖像翹曲和變形變換[1729]和廣義投影[638]。通過(guò)在CPU或著色器中應(yīng)用函數(shù)见芹,可以創(chuàng)建許多更精細(xì)的效果剂娄。
通過(guò)使用紋理混合技術(shù),可以實(shí)現(xiàn)其他動(dòng)畫(huà)效果玄呛。例如阅懦,從大理石紋理開(kāi)始,逐漸淡化為肉質(zhì)紋理徘铝,就可以使雕像栩栩如生[1215]耳胎。
6.5 材質(zhì)映射 Material Mapping
紋理的一個(gè)常見(jiàn)用途是修改影響著色方程的材質(zhì)屬性。現(xiàn)實(shí)世界中的物體通常具有不同表面的物質(zhì)屬性惕它。為了模擬這樣的對(duì)象怕午,像素著色器可以從紋理中讀取值,并在計(jì)算陰影方程之前使用它們修改材質(zhì)參數(shù)淹魄。最常被紋理修改的參數(shù)是表面顏色郁惜。這種紋理被稱(chēng)為albedo color map或漫diffuse color map。但是甲锡,任何參數(shù)都可以通過(guò)紋理進(jìn)行修改:替換它兆蕉、乘以它或以其他方式更改它。例如缤沦,在圖6.25中虎韵,三個(gè)不同的紋理被應(yīng)用到一個(gè)表面,替換了常量值缸废。
紋理在材料中的使用可以更進(jìn)一步劝术。紋理可以用來(lái)控制像素著色器本身的流和功能,而不是修改方程中的參數(shù)呆奕。兩個(gè)或多個(gè)材質(zhì)具有不同的著色方程和參數(shù)养晋,可以通過(guò)使用一個(gè)紋理指定表面的哪些區(qū)域具有哪些材質(zhì)來(lái)應(yīng)用于一個(gè)表面,從而為每個(gè)材質(zhì)執(zhí)行不同的代碼梁钾。例如绳泉,有一些生銹區(qū)域的金屬表面可以使用紋理來(lái)指示生銹的位置,根據(jù)紋理查找有條件地執(zhí)行著色器生銹的部分姆泻,否則執(zhí)行閃亮的金屬著色器(第9.5.2節(jié))零酪。
著色模型的輸入冒嫡,如表面顏色,與著色器的最終顏色輸出有線(xiàn)性關(guān)系四苇。因此孝凌,包含這些輸入的紋理可以用標(biāo)準(zhǔn)技術(shù)過(guò)濾,避免了混疊月腋。包含非線(xiàn)性陰影輸入的紋理蟀架,如粗糙度或凹凸貼圖(章節(jié)6.7),需要更多的注意來(lái)避免混疊榆骚∑模考慮到陰影方程的濾波技術(shù)可以提高這些紋理的效果。這些技術(shù)將在第9.13節(jié)中討論妓肢。