紋理過濾相關內容

2021-06-22 16:35:59 字數 4201 閱讀 1601

最近的工作涉及到了紋理過濾的知識,然後就開始回想起來以前的儲備知識,結果發現自己的儲備簡直是弱爆了,因此查了點資料,總計寫記錄下來,一邊以後翻閱

d3d支援的紋理過濾型別是3中:

最近點取樣,

線性紋理過濾, 

各向異性(anisotropic)紋理過濾

但是在遊戲中一般會分為4種:

點取樣、設定方式:

g_device->setsamplerstate(0,d3dsamp_magfilter, d3dtexf_point);

g_device->setsamplerstate(0, d3dsamp_minfilter, d3dtexf_point); //

g_device->setsamplerstate(0, d3dsamp_mipfilter, d3dtexf_point);

g_device->setsamplerstate(0, d3dsamp_maxmiplevel, 16);

或者 g_device->setsamplerstate(0, d3dsamp_mipfilter, 

d3dtexf_none

);雙線過濾(即d3d的線性紋理過濾),

g_device->setsamplerstate(0,d3dsamp_magfilter, d3dtexf_linear

);g_device->setsamplerstate(0, d3dsamp_minfilter, d3dtexf_linear);

g_device->setsamplerstate(0, d3dsamp_mipfilter, d3dtexf_point);

g_device->setsamplerstate(0, d3dsamp_maxmiplevel, 16);

三線過濾(即 d3d中的線性過濾加上mipmap),(mipmap就是指多級漸進形紋理)

g_device->setsamplerstate(0,d3dsamp_magfilter, d3dtexf_linear

);g_device->setsamplerstate(0, d3dsamp_minfilter, d3dtexf_linear);

g_device->setsamplerstate(0, d3dsamp_mipfilter, 

d3dtexf_linear);

g_device->setsamplerstate(0, d3dsamp_maxmiplevel, 16);

各向異性過濾

g_device->setsamplerstate(0,d3dsamp_magfilter, d3dtexf_anisotropic);

g_device->setsamplerstate(0, d3dsamp_minfilter, d3dtexf_anisotropic);

g_device->setsamplerstate(0, d3dsamp_maxanisotropy, 4);

總之多級漸進性紋理和d3d三種基本的紋理過濾方式搭配使用 ,產生了很多豐富的效果。

以下的這段話很關鍵:

首先從mipmap的原理說起,它是把一張貼圖按照2的倍數進行縮小。直到1x1。把縮小的圖都儲存起來。在渲染時,根據乙個畫素離眼睛為之的距離,來判斷從乙個合適的圖層中取出texel顏色賦值給畫素。在d3d和ogl都有相對應的api控制接

口透過它的工作原理我們可以發現,硬體總是根據眼睛到目標的距離,來玄奇最適合當前螢幕畫素解析度的圖層。假設一張32768x32768的mipmap貼圖,當前螢幕解析度為1024*1024。眼睛距離物體比較近時,mipmap最大也只可能從1024*1024的mipmap圖層選取texel。再次,當使用三線性過濾(trilinear)時,最大也只能訪問2048*2048的圖層選取texel,來和1024*1024圖層中的畫素進行線性插值。

為了加快渲染速度和減少影象鋸齒,貼圖被處理成由一系列被預先計算和優化過的組成的檔案,這樣的貼圖被稱為 mip map 或者 mipmap

多級漸進紋理由一組解析度逐漸降低的紋理序列組成,每一級紋理寬度和高度都是上一級紋理寬度和高度的一半。寬和高不一定相等,也就是說,這些紋理不一定都是正方形。

direct3d在紋理對映時,自動選擇一幅與物體大小最接近的紋理進行渲染。當物體離投影平面較遠時,direct3d會選擇一張尺寸較小、解析度較低的紋理進行渲染;當物體離投影平面較近時,direct3d會選擇一張尺寸較大、解析度較高的紋理進行渲染。direct3d將紋理序列看成一條多級漸進紋理鏈。鏈頭處紋理的解析度最高,下一級往後依次遞減,鏈尾處紋理的解析度最低。

direct3d能估計出多級漸進紋理鏈中哪幅紋理的解析度最接近想要的輸出結果,然後它將畫素對映到紋理空間。當最終顯示的圖形大小介於任意兩級紋理圖形之間

時,direct3d將兩級紋理的相應元素進行混合後顯示。

多級漸進紋理過濾能夠有效地提高圖形渲染速度,當物體離投影平面較遠時,direct3d會選擇一張尺寸較小的紋理進行渲染,而無需經過複雜的諸如各項異性紋理過濾,並且由於這時紋理需要的視訊記憶體比不使用多級漸進紋理時小,因此能有效地減少紋理載入視訊記憶體的時間。

缺點是對記憶體的要求比較高

///

16位色的256*256的紋理使用128k記憶體,如果在該紋理中再加乙個多紋理對映還需要額外的43k記憶體

/// 原因在這

設定多級漸進紋理過濾方式

當最終顯示的紋理貼圖大小介於任意兩級紋理之間時,direct3d能夠取得兩級紋理元素進行混合後顯示,具體的混合方式由指定的多級漸進紋理過濾方式決定。可以呼叫函式idirect3ddevice9::setsamplerstate()設定多級漸進紋理過濾方式,將第乙個引數設為紋理層序號,第二個引數設為d3dsamp_mipfilter表示多級漸進紋理過濾,第三個引數設為在相鄰紋理級之間的過濾方式,可取列舉型別d3dtexturefiltertype的任意值。下面的示例**設定相鄰紋理級之間的過濾方式為線性過濾。

g_device->setsamplerstate(0, d3dsamp_mipfilter, d3dtexf_linear);

如果將第三個引數設為d3dtexf_none,那麼就會一直使用最高一級的紋理,即禁用多級漸進紋理過濾。如果將其設為d3dtexf_point,就會只使用與圖元大小最匹配的一級紋理。如果將其設為d3dtexf_linear,direct3d就將與圖元大小最匹配的兩級紋理以線性方式混合。

需要注意的是,多級紋理過濾是縮小和放大過濾器的結合。例如,如果將縮小和方法過濾器設為線性過濾,但是多級紋理過濾方式設為最近點取樣,direct3d就會選擇與要顯示的紋理貼圖大小最接近的紋理級別,在該級紋理上完成雙線性紋理過濾,並將結果作為畫素的值。如果將縮小、放大過濾器和多級漸進紋理都設定為線性過濾,則direct3d就會在兩個最接近的紋理級別上都進行雙線性紋理過濾,然後再對相鄰兩級紋理圖形上對應的兩個紋理顏色進行加權平均,最後的結果作為單個畫素值。這種為了圖元中的乙個畫素,而結合了兩幅紋理,共8個畫素的技術,稱為「三線性過濾」,因為它在紋理的三個方向----u、 v和紋理級別上都進行了線性過濾。

可以通過idirect3ddevice9::setsamplerstate()函式設定實際渲染時紋理過濾的最大級數,其中需要將第二個引數設為d3dsamp_maxmiplevel,第三個引數設為實際渲染時紋理過濾的最大級數。下面的示例**設定紋理層0的最大多級紋理過濾級數為16。

g_device->setsamplerstate(0, d3dsamp_maxmiplevel, 16);

還可以通過將idirect3ddevice9::setsamplerstate()的第二個引數設為d3dsamp_mipmaplodbias,設定多級紋理對映級數偏移值。如果對某個紋理對映設定正偏移值,得到的圖形結果就會比原來的更清晰,但鋸齒更多;反之設為負偏移值,得到的圖形結果就會更模糊。

以下這段話也很重要:

mipmap:由一系列紋理組成,其中每張紋理的高寬都是前一級高寬的一半。d3d在渲染時會自動挑選出乙個圖素與畫素的比值最接近於1的mip層級。

最近點取樣:將紋理座標對齊到最接近的整數,再將那個位於整數座標上的紋理畫素作為最終的顏色。缺點:容易在影象邊界上造成錯誤,優點:快。

線性紋理過濾:(即雙線紋理過濾),計算相對於取樣點最近的4各圖素(上下左右4個點)的平均值。缺點:有各項異性失真可能。

三線過濾:對於每個畫素,三線過濾會先選擇兩張最接近的mipmap,將它們雙線過濾為兩張理想大小的mipmap,然後根據理想的mip級組合這兩張過濾後的mipmap中的對應畫素。缺點:有各項異性失真可能。

各項異性過濾:根據螢幕畫素的伸張度來測量各項異性,再將螢幕畫素反向對映到紋理空間中。效果:在非水平的渲染時要比三線過濾更加銳化。

紋理過濾相關內容

最近的工作涉及到了紋理過濾的知識,然後就開始回想起來以前的儲備知識,結果發現自己的儲備簡直是弱爆了,因此查了點資料,總計寫記錄下來,一邊以後翻閱 d3d支援的紋理過濾型別是3中 最近點取樣,線性紋理過濾,各向異性 anisotropic 紋理過濾 但是在遊戲中一般會分為4種 點取樣 設定方式 g d...

ORACLE相關內容

1 em,dbca,netca,netmgr出現亂碼方案 cd oracle home jre lib mv font.properties font.properties.bak mv font.properties.zh font.properties em,dbca,netca,netmgr詳...

JVM相關內容

本地 native code 每個因素對記憶體占用的影響又會隨著應用程式 執行環境和系統平台的不同而變化,那怎樣計算總的記憶體佔用量?是的,想得到乙個準確的數字不是那麼容易,因為 你很難控制本地 native 部分。你能控制的部分只有堆大小 xmx,類占用的記憶體 xx maxpermsize,還有...