翻譯文
原文標題:Android Lesson Six: An Introduction to Texture Filtering
原文鏈接:http://www.learnopengles.com/android-lesson-six-an-introduction-to-texture-filtering/
介紹紋理過濾
這節(jié)課舵变,我們將介紹基本紋理過濾的不同類型和怎樣使用它們粉臊, 包括最鄰近(nearest-neighbour)過濾,雙線性(bilinear)過濾吧趣, 和使用mipmap的三線性(trilinear)過濾任内。 你將學習如何使紋理看起來更平滑赞哗,以及平滑帶來的缺點。 [這兒有旋轉物體][]的不同方式郎楼,本課使用了其中一万伤。 |
![]() screenshot
|
前提條件
強烈建議您先閱讀OpenGL Android課程四:介紹紋理基礎,理解紋理映射在OpenGL中的基本使用呜袁。
什么是紋理過濾敌买?
OpenGLES中的紋理由元素數組組成,被稱為紋素(texels)阶界,其中包含顏色和alpha值虹钮。這與顯示器相對應,顯示器由一堆像素組成膘融,并在每個點顯示不同的顏色芙粱。在OpenGL中紋理被用在三角形上并繪制到屏幕,因此這些紋理能繪制出各種各樣的尺寸和方向氧映。OpenGL中的紋理過濾選項告訴它如何根據具體情況將紋理像素過濾到設備的像素上春畔。
有三種情況:
- 每個紋素映射到多個像素,這被稱為放大(magnification)
- 每個紋素精確的映射到一個像素,過濾不適合這種情況
- 每個紋素映射少于一個像素律姨,這被稱為縮小(minification)
OpenGL允許我們?yōu)榉糯蠛涂s小分配過濾器振峻,并允許我們使用最鄰近、雙線性和三線性過濾择份。我們將在下面解釋這些意思扣孟。
放大和縮小
這里是放大和縮小的最鄰近渲染的可視化,當您用USB連接你的Android設備時使用這個可愛的Android顯示成功連接荣赶。
![cute android](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221100843.png)
放大
![magnification android](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221100936.png)
正如您所見凤价,紋素現(xiàn)在很容易看到,因為當前一個紋素覆蓋了很多像素展示出來讯壶。
縮小
![minification android](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221101211.png)
隨著縮小料仗,許多紋素不能渲染到有限的像素上,許多細節(jié)將會丟失伏蚊。
紋理過濾模式
雙線性插值(Bilinear interpolation)
當紋素值之間沒有插值時,在放大示例中格粪,紋理的紋素清晰可見為大正方形躏吊。當使用最鄰近方式時,像素將會分配到最鄰近的像素帐萎。
通過切換到雙線性插值比伏,渲染質量顯著提高。這些值將會在鄰近的四個像素之間線性插值疆导,而不是將一組像素分配給鄰近相同的紋素值赁项。每個像素被平滑化,使得最后的圖片看起來也更平滑:
![smoother android](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221103115.png)
一些塊效果仍然很明顯澈段,但是這個圖片看起來比之前更加平滑悠菜。那些在3D加速卡出現(xiàn)前玩過3D游戲的人將會記得軟件渲染游戲和硬件加速游戲之間的特性:軟件渲染游戲根本沒有進行預計算處理,所以一切都顯示得塊狀和鋸齒狀败富。一旦人們開始使用圖形加速悔醋,這些東西都將變得平滑。
![smooth](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221104453.png)
雙線性插值大多使用在放大兽叮。它也能使用在縮小芬骄,但是超過某個度,我們將會遇到同樣的問題鹦聪,我們在嘗試將太多的紋素放到相同的像素上账阻。OpenGL僅使用最多4個紋素渲染一個像素,因此許多信息仍然會丟失泽本。
如果我們看應用了雙線性插值的紋理淘太,當我們在遠處看它移動時看起來會很嘈雜,因為每幀都會選擇不同的紋素。
紋理映射(Mipmapping)
我們如何才能在縮小紋理時不引用嘈雜并使用上所有紋素呢琴儿?我們可以生成一組優(yōu)化后的不同尺寸的紋理段化,然后在我們運行的時候使用它們。由于這些紋理已預先生成造成,它們能使用更多高昂的技術去過濾所有紋素显熏,并且在運行時OpenGL會根據紋理在屏幕上的最終大小選擇最合適的層。
![textures set](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221143838.png)
生成的圖片可以具有更多細節(jié)晒屎,更少噪點喘蟆,并且整體上看起來更好。盡管需要更多的內存鼓鲁,但渲染速度也會更快蕴轨,因為較小的層級能更容易保存在GPU的紋理緩存中。讓我們來仔細研究一下原尺寸的1/8倍的圖片骇吭,在使用了雙線性過濾使用紋理映射和雙線性過濾沒有使用映射橙弱。為了清楚圖片已被擴大:
雙線性過濾沒有mipmap
![without mipmaps](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221145134.png)
雙線性過濾+mipmap
![with mipmaps](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221145249.png)
使用mipmap的版本擁有更多細節(jié),由于圖像預處理到單獨的層級燥狰,所有紋素最終都會在最終的圖像中使用棘脐。
三線性過濾(Trilinear filtering)
當使用雙線性過濾的mipmap時,有時在渲染場景中可以看到明顯的跳躍或線龙致,由于OpenGL在紋理的不同mipmap層級之間切換蛀缝。比較不同的OpenGL紋理的過濾模式將在下面進一步指出。
三線性插值通過在不同mipmap層級之間插值來解決這個問題目代,這樣總共8個紋素將用于插值得到最終的像素值屈梁,使得圖像更平滑。
OpenGL 紋理過濾模式
OpenGL有兩個可被設置的參數:
-
GL_TEXTURE_MIN_FILTER
紋理縮小時的過濾模式 -
GL_TEXTURE_MAG_FILTER
紋理放大時的過濾模式
這些相對應于上面的縮小和放大描述榛了。
-
GL_TEXTURE_MIN_FILTER
接受以下選項:GL_NEAREST
GL_LINEAR
GL_NEAREST_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR
GL_LINEAR_MIPMAP_NEAREST
GL_LINEAR_MIPMAP_LINEAR
-
GL_TEXTURE_MAG_FILTER
接受以下選項:GL_NEAREST
GL_LINEAR
GL_NEAREST
對應最鄰近渲染在讶;
GL_LINEAR
對應雙線性過濾;
GL_LINEAR_MIPMAP_NEAREST
對應雙線性過濾+mipmap忽冻;
GL_LINEAR_MIPMAP_LINEAR
對應三線性過濾真朗;
本課中將進一步介紹圖形示例和最常見選項的進一步說明。
怎樣設置紋理過濾模式
我們首先需要綁定紋理僧诚,然后我們在這個紋理上設置合適的過濾參數:
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureHandle);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, filter);
怎樣生成mipmap
這真的很容易遮婶!在加載紋理到OpenGL中后,紋理仍然是綁定的湖笨,我們可以簡單的調用:
GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
它將為我們生成所有的mipmap層級旗扑,并且這些層級會根據紋理過濾自動使用。
它看起來怎么樣慈省?
以下是可用的最常見的組合的屏幕截圖臀防,當你看到它運動中時,效果更加引人注目,因此我建議下載這個App并試一試袱衷。
最鄰近渲染
這個模式讓人想起舊版3D游戲軟件的渲染捎废。
GL_TEXTURE_MIN_FILTER = GL_NEAREST
GL_TEXTURE_MAG_FILTER = GL_NEAREST
![nearest nearest](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221163746.png)
雙線性過濾,mipmap
許多支持3D加速的首批游戲都使用此模式致燥,這是今天在Android手機上平滑紋理的有效方式登疗。
GL_TEXTURE_MIN_FILTER = GL_LINEAR_MIPMAP_NEAREST
GL_TEXTURE_MAG_FILTER = GL_LINEAR
![linear mipmap](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221164349.png)
靜態(tài)圖上很難看圖問題,但是當物體運動時嫌蚤,您可能會注意到渲染的像素在mipmap層級之間切換的水平條帶辐益。
三線性過濾
此模式通過在mipmap層級之間進行插值,改進了使用mipmap的雙線性過濾的渲染質量脱吱。
GL_TEXTURE_MIN_FILTER = GL_LINEAR_MIPMAP_LINEAR
GL_TEXTURE_MAG_FILTER = GL_LINEAR
![trilinear](https://raw.githubusercontent.com/xujiaji/xujiaji.github.io/pictures/blog/learn-opengl/20190221165703.png)
像素在近距離和遠距離之間完全平滑智政;事實上,紋理現(xiàn)在可能在傾斜角度下顯示的過于平滑箱蝠。
各向異性過濾(Anisotropic filtering)是一種更先進的技術续捂,受到某些移動GPU的支持,可用于改善最終結果抡锈,超出三線性過濾所能提供的效果疾忍。
進一步練習
使用其他模式可以達到什么樣的效果?例如床三,您何時會使用像GL_NEAREST_MIPMAP_LINEAR
這樣的東西?
教程目錄
- OpenGL Android課程一:入門
- OpenGL Android課程二:環(huán)境光和漫射光
- OpenGL Android課程三:使用每片段照明
- OpenGL Android課程四:介紹紋理基礎
- OpenGL Android課程五:介紹混合(Blending)
- OpenGL Android課程六:介紹紋理過濾
打包教材
可以在Github下載本課程源代碼:下載項目
本課的編譯版本也可以再Android市場下:google play 下載apk
“我”也編譯了個apk杨幼,方便大家下載:github download