Basic Texturing(基本紋理技術)

這幾天一直都在看baisc texturing ,這一節寫的是太精彩了,原本只是瞭解大致原理,細節基本很模糊的我,居然對texturing有了比較清晰的理解。爲了幫助我更好的理解,我有必要寫點讀書筆記。

我們知道,通過光照計算和設置材質屬性,我們可以爲每個頂點計算一個顏色值;利用vetex shader,我們可以擴展固定流水線的功能,並且可以每個頂點隨意計算其顏色值。利用這兩種方法建模的顏色值,能夠通過光柵器插值到屏幕中對應的像素中。但是,僅僅通過這兩種方法,很難爲物體做一個非常精細的“面孔”,所以就引入了Texturing 技術。

    紋理化技術,能把一張很複雜的圖片繪製在物體的表面,它也可以允許我們爲每個像素建立一張漫反射表,其索引可以通過每個對應被插值的頂點的紋理座標計算得到。紋理的每個元素就好比對應一個像素,都是一個color。紋理座標一般是有一維,兩維,三維和四維。把查詢漫反射表的結果與光柵化的結果混合起來,能產生一個漫反射顏色,一起送給frame buffer。當然,它也能支持multi texturing,每個texturing stage 的output 也就是下一個stage的input。

    固定功能的像素處理通過multi texturing 各個stage來產生豐富的顏色。可編程的pixel shader,當然就非常靈活的產生顏色了。

    現在主要有三種紋理資源,矩形紋理,立方體紋理以及大體積紋理(volume)。在這一章討論了紋理資源的接口以及紋理資源的管理,並且詳細的解釋了紋理座標的處理(非常精彩)。

   紋理座標是由vertex buffer提供的或者由direct3d自動產生。在提交到teuring stage之前,紋理座標能通過矩陣進行變換。不過,一旦紋理座標綁定到一個源像素,這個紋理就會與一個stage綁定。這一章詳細講解了紋理採樣技術,使用不同的紋理採樣方法,將會得到不同的效果。

 

紋理座標的處理

  理論上紋理座標值範圍在【0,1】,如線性紋理和矩形紋理。但是立方體紋理有點不一樣,它的值範圍是在【-1,1】,而且它的每個面上的紋理值都有一個值是-1或者1,其立方體的中心是其(0,0,0)位置。

 在頂點被轉化到屏幕空間後,光柵將其紋理進行插值,這樣就可以計算出來一個像素上紋理座標的變化值。如果把這個變化值乘以紋理的分辨率,就可以得到一個像素對應多少個紋理像素。利用這個信息,我們就可以選擇mipmap level。

   但是很多時候,我們需要直接將紋理像素值映射到屏幕中去,如用戶界面。爲了取得一對一的效果,primitive的位置相對屏幕空間位置得偏移0.5,這是因爲三角形的光柵化規則,整數座標位置是像素的中心位置,這個偏移可以使三角形位置正好對應於像素位置,這種效果可以很容易通過變換後頂點實現,因爲它們的座標已經是屏幕空間的座標了。詳細解釋可以參考 DirectX SDK document ("Mapping Texels to Pixels")。

   頂點可以攜帶多組紋理座標,默認第一組對應texturing的第一個階段。TSS Tex Coord Index可以用來控制哪個stage 使用哪組座標。

   Direct3D也會自動爲頂點產生紋理座標。

   紋理座標也可以通過變換矩陣進行轉換,轉換矩陣一般是一個4*4矩陣的左上方的子矩陣,它的維度取決於紋理的維度和TSS Texture Transform Flag。

紋理尋址

   雖然紋理座標一般是在【0,1】區間,但是你同樣可以使用這個範圍之外的紋理值,如(2,3)。D3DCAPS的MaxTextureRepeat 可以設置設置紋理區間的範圍,比如如果這個值是5,設備支持的紋理座標的區間就是【-5,5】。如果TextureCaps 的D3DTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE沒有被設置,在進行插值之前設備將紋理座標放大到紋理的實際尺寸,MaxTexureRepeat 實際上指定了座標放大後能被設備支持的範圍。

在單位區間之外的紋理座標處理方式是通過紋理的尋址模式設置的,尋址模式包括Wrap, Mirror,Clamp,Border,MirrorOnce。默認是Wrap模式。

紋理 Wrapping

紋理wrapping是用於調節光柵器對紋理座標進行插值的方式,注意千萬不要將紋理的Wrapping 與尋址模式wrap 混爲一談,紋理wrapping 是通過每個stage的 render state的 RS wrap 0到RS wrap 15。啓用wraping,光柵器插值就會採用紋理空間兩個個座標的最短路徑的方法來實現,這裏紋理空間被視爲一個無限重複的網格。

紋理採樣

紋理採樣就是爲每個像素選取紋理像素的操作。如果在一個像素對應的紋理空間尺寸是2的冪,並且也有一個miplevel 的紋理與它對應,這個時候採樣能直接從這個miplevel的紋理採樣。但是大多數時候,一個像素所對應的紋理像素空間不是2的冪。Direct3D 提供了3種紋理stage state來控制紋理的採樣:SS Min Filter(紋理被縮小), SS max Filter(紋理被放大), SS Mip Filter(紋理被Mipmap)。這三種狀態都可取值於D3DTEXTUREFILTERTYPE(D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC, D3DTEXF_FLATCUBIC, D3DTEXF_GAUSSIANCUBIC)。 在縮小化過程中,SS Min Filter將指定幾個紋理像素怎麼樣合成一個像素值。 在放大過程中,SS Max Filter 怎麼樣插值紋理樣例。除了只從一個紋理的mip level 取樣外,我們可以從兩個相鄰的mip level取樣,用SS Mip Filter來合成它們,用這種方法,當基本元素在場景裏面移動或者紋理縮小量和放大量變化的時候,能產生比較平滑的過渡。

 

並不是所有的D3DTEXTUREFILTERTYPE的值都能應用到這三種狀態。 D3DTEXF_POINT 和 D3DTEXF_LINEAR 能所有這三種狀態, D3DTEXF_NONE 能被用於禁止mipmap。 D3DTEXF_ANISOTROPIC能被用於放大與縮小,然而,D3DTEXF_PYRAMIDALQUAD和D3DTEXF_GAUSSIANQUAD只能用戶放大過濾。

點過濾選擇離像素對應的紋理座標最近的紋理像素或者mip map level。線性過濾,當用於放大與縮小的時候,選擇相鄰的四個紋理像素,用紋理座標進行線性插值來獲得,當用於mip level的時候,選擇相鄰的兩個mip level,從他們之間採取線性插值採樣。在線性mip level 插值的時候,先分別通過縮小和放大來取得采得連個mip level的樣。 立方體過濾器提供更加精確的採樣,他們通過3*3 相鄰像素進行線性插值。

Anisotropic過濾可以用於非正方形區域的紋理採樣。

紋理階段處理

當一個紋理被地址化和被採樣以後,紋理像素值就會產生。這個紋理像素值可以結合其他的input在一個紋理stage中來爲像素產生一個新的diffuse顏色值。這個diffuse 能被傳遞到下一個Stage進行進一步的處理。每一個紋理stage處理包括一個RGB單元處理和一個alpha單元處理。這兩個單元處理在direct3D中是獨立的,串聯起來的。你要分別設置這兩個單元的狀態。每個單元處理能從6個輸入通道中選擇3個作爲它的參數。這兩個單元處理後的結果也能夠被送到兩種可能目的地(Current, Temp)之一做進一步的處理。

6個輸入通道包括:來自光柵器的被插值的diffuse , 來自光柵器的被插值的specular, 當前紋理取樣的紋理像素,RS Texture Factor 值,前一個紋理Stage的結果和臨時紋理stage寄存器裏面的內容。這裏的每個輸入都有一個值與之對應。D3DTA_SELECTMASK可以用來選擇這6個輸入通道。

RGB 和alpha處理單元都能夠計算多達3個參數的函數。每個參數都綁定到一個輸入通道。 TSS Color Arg 0, TSS Color Arg1, TSS Color Arg2, TSS Alpha Arg 0 , TSS Alpha Arg 1, TSS Alpha Arg 2,分別代表各個參數。 TSS Color Op 和 TSS Alpha Op表示對應的函數。TSS Result Arg 指定輸出結果。

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