注:本文使用的全部 OpenGL 函數來自 OpenGL 4.5,優先使用 DSA。markdown
使用 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。計算 λ 和 ρ 的方程以下:
ide
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 來表示:
除了計算 λ 時控制 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 級別。使用這個方法,隨着加載愈來愈多的紋理數據,屏幕上的圖像將得到愈來愈高的逼真度。