【转】OpenGL随笔(1)—— mipmap 详解
【轉】OpenGL隨筆(1)—— mipmap 詳解
注:本文使用的所有 OpenGL 函數來自 OpenGL 4.5,優先使用 DSA。
使用 mipmap 時,OpenGL 根據被映射對象的大小(單位是像素),自動決定使用紋理圖的哪個分辨率級別。mipmap 表示著紋理的層次細節(LOD),隨著對象圖像變小,使用紋理圖的大小將減少。mipmap 需要一些額外的計算和紋理存儲空間(大概三分之一),但這些消耗是值得的,如果不使用 mipmap ,那么映射到更小圖像上的紋理將隨著物體移動而閃爍。?
OpenGL 的 mipmap 省去了紋素大小和多邊形大小的縮放因子 λ 的詳細討論,不更改則使用默認值。下文將使用默認的 mipmap 參數,最后會討論控制 λ 的細節。?
參數 GL_TEXTURE_MIN_FILTER 控制在 mipmap 級數大于 0 時如何重建紋素。這個參數共有 6 個設置。前兩個與用于放大的相同,GL_NEAREST 和 GL_LINEAR。選擇這兩個參數會禁用 mipmap,OpenGL 將使用紋理的基數級(級數0)。其他四個模式啟用 mipmap,并控制著 mipmap 的使用。這四個值分別是 GL_NEAREST_MIPMAP_NEAREST、GL_LINEAR_MIPMAP_NEAREST、GL_NEAREST_MIPMAP_LINEAR、GL_LINEAR_MIPMAP_LINEAR。名字結構的第一部分控制紋素的構造,表示當前采用紋理的構造方式;第二部分控制 mipmap 級之間采樣模式,NEAREST 表示只使用最近的 mipmap 級,LINEAR 則表示最近的兩個 mipmap 線性插值。?
為了使用 mipmap,必須提供紋理在最大尺寸和 1x1 圖之間的所有大小是 2 的冪的紋理級別。如果不想使用 mipmap 到 1x1 紋理的所有變化,可以將 GL_TEXTURE_MAX_LEVEL 的值設置為提供的最大級數,并且 OpenGL 不會考慮更進一步的級別。如果紋理最高級別的分辨率不是正方形,那么一個維度將比另外一個首先到達大小為 1 的紋素。在這種情況下,將繼續對這個維度創建新的層級,直到兩個維度到達 1x1 的形式為止。例如,如果最高分辨率是 64x16,則必須提供大小 32x8,16x4,8x2,4x1,2x1 和 1x1。mipmap 小圖紋素的獲取對應于大圖 4 個紋素的加權平均。?
需要特別注意的一點是 glTextureStorage* 生成的紋理空間是不可變的,也就是說不可以使用 glGenerateTextureMipmap 來自動生成函數,而只能用 glTextrueSubImage2D 來手動載入各級紋理;試圖讓 OpenGL 自動生成 mipmap,請使用 glTextureImage*。?
OpenGL 提供一個函數,其在應用程序的控制下為紋理自動生成所有的 mipmap—— glGenerateTextureMipmap。在 OpenGL 實現中,它提供了通過采樣高分辨率圖像來生成更低分辨率圖像的一個機制。這通常使用著色器和紋理濾波硬件來實現。這個技術通常被設計用于性能多于質量,并且在不同的實現之間有變化。如果想要高質量的結果,最好自己生成和提供 mipmap 圖像。如果需要快速生成 mipmap 鏈并且對獲得的任何結果都滿意,可以使用 glGenerateTextureMipmap 函數。?
計算特定像素的紋理級別時,其結果取決于紋理圖像和紋理映射的多邊形大小比例因子。我們稱這個比例因子為?ρ,再定義第二個值?λ,且?λ=log2ρ+lodbias(因為紋理圖像可以是多維的,所以聲明?ρ?是所有維的最大比例因子是很重要)。?
lodbias?是采樣器的細節層次偏移,在 glSamplerParameteri 中設置參數為 GL_TEXTURE_LOD_BIAS 來修改它,從而修改?λ。默認?lodbias=0.0,如果?λ≤0.0,意味著紋素小于像素,所以使用放濾波器。如果?λ>0.0,則使用縮小濾波器。如果縮小濾波器使用 mipmap,那么?λ?是 mipmap 級別。?
例如,如果紋理圖像是 64x64 像素,多邊形大小是 32x32 像素,那么?ρ=2.0(單個維度的比值),則?λ=1.0。如果紋理圖像是 64x32 紋素,并且多邊形尺寸是 8x16 像素,那么?ρ=8.0(x?比例是?8.0,y?比例是?2.0,則使用最大值),因此?λ=3.0。計算?λ?和?ρ?的方程如下:?
λ′(x,y)=λbase+clamp(biastexobj+biasshader
Mipmap 級別的計算可以進一步通過一些采樣器參數來控制。GL_TEXTURE_LOD_BIAS 可以用來偏移 λ。計算 λ 后,可以截取邊界到用戶設置的范圍。這通過參數 GL_TEXTURE_MIN_LOD 和 GL_TEXTURE_MAX_LOD 給出,可以通過函數 glSamplerParameterf 或 glTextureParameterf 來設置。GL_TEXTURE_MIN_LOD 和 GL_TEXTURE_MAX_LOD 默認值分別為 -1000.0 和 1000.0。GL_TEXTURE_MIN_LOD 和 GL_TEXTURE_MAX_LOD 在下式中分別用?lodmin?和?lodmax?來表示:?
λ=???????lodmax,λ′,lodmin,undefined,λ′>lodmaxlodmin≤λ′≤lodmaxλ′<lodminlodmin>lodmax
除了計算 λ 時控制?lodmin、lodmax?和?λbase?的參數,通過 GL_TEXTURE_BASE_LEVEL 和 GL_TEXTURE_MAX_LEVEL 參數來提供 mipmap 選擇 level 的進一步控制,這些參數使用 glSamplerParameteri 來設置。GL_TEXTURE_BASE_LEVEL 設置被采樣的最低 mipmap 級別(最高分辨率), GL_TEXTURE_MAX_LEVEL 設置被采樣的最高 mipmap 級別(最低分辨率),用來限制采樣級別范圍。?
GL_TEXTURE_BASE_LEVEL 的一個潛在的用處是紋理流。使用紋理流時,完整紋理對象的存儲使用函數(例如 glTextureStorage2D)分配但沒有加載初始數據。隨著應用程序的運行,新對象進入視野,加載從最低到最高分辨率的紋理數據。即使還沒有加載完整的紋理,但為了保證有意義的東西顯示給用戶,可以設置 GL_TEXTURE_BASE_LEVEL 的值為已經加載的最高分辨率 mipmap 級別。使用這個方法,隨著加載越來越多的紋理數據,屏幕上的圖像將獲得越來越高的逼真度。
?
參考:The OpenGL? Programming Guide 9th Edition
版權聲明:轉載請附帶本文地址,謝謝~ 原文地址:http://blog.csdn.net/qq_33274326/article/details/54866088posted on 2018-02-15 23:03 時空觀察者9號 閱讀(...) 評論(...) 編輯 收藏
總結
以上是生活随笔為你收集整理的【转】OpenGL随笔(1)—— mipmap 详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++数组与指针回顾总结
- 下一篇: 【转】矩阵的几何解释