【URP】Unity中Mipmap Streaming原理與實現
【從UnityURP開始探索游戲渲染】專欄-直達
紋理流送技術,其核心在于動態加載紋理的 Mipmap 級別,而非一次性加載所有層級的紋理數據。傳統 Mipmap 會預生成并加載所有層級的紋理(從原始尺寸到最小尺寸),占用顯存為原始紋理的 4/3 倍。
Mipmap Streaming 優化機制:
?分級加載?:
- 根據物體與攝像機的距離,僅加載當前所需的 Mip 層級,其他層級按需從磁盤異步加載。
?DDX/DDY 計算?:
- GPU 通過內部值 DDX 和 DDY(基于像素的 UV 坐標變化率)動態決定采樣所需的 Mip 層級,匹配像素覆蓋的 Texel 大小。
?紋理金字塔管理?:
- Unity 維護一個紋理金字塔(14 個層級,最高支持 8192x8192),運行時僅激活必要的層級。
解決的問題
?顯存優化?:
- 避免一次性加載所有 Mip 層級,顯著降低顯存占用,尤其對移動端(如 HUAWEI P30 測試案例)和高分辨率紋理場景至關重要。
?帶寬效率?:
- 減少 GPU 帶寬壓力,僅傳輸可見層級的紋理數據,提升渲染性能。
?摩爾紋消除?:
- 通過動態匹配 Mip 層級,避免遠距離物體因像素與 Texel 不匹配產生的鋸齒和摩爾紋。
原理詳解
當物體遠離攝像機時主要流程:
- GPU 通過 DDX/DDY 計算當前像素覆蓋的 Texel 面積,選擇 Mip 10(512x512)。
- Unity 釋放更高層級的顯存(如 Mip 11-12),從磁盤按需加載更低層級(如 Mip 9)。
- 若物體突然靠近,高優先級層級的 Mip 會優先加載,避免視覺卡頓。
?Mip 層級選擇計算?
- GPU 通過 DDX/DDY 導數計算當前像素的 UV 變化率,推導出紋理采樣所需的理想 Mip 層級(記為
MipLevelideal)。例如,當物體遠離攝像機時,UV 變化率降低,MipLevelideal值增大(選擇更低分辨率的層級)。
?層級動態加載與卸載?
- Unity 僅將
MipLevelideal及其相鄰層級(如 ±1 級)加載到顯存,其他層級保留在磁盤。例如:- 若
MipLevelideal=4(對應 256x256 紋理),則加載 Mip 3-5 級,卸載其他層級。 - 通過
Texture2D.streamingMipmaps屬性可強制指定加載特定層級(如MipLevelideal+2)。
- 若
?內存預算控制?
- 系統根據
QualitySettings.streamingMipmapsMemoryBudget全局預算動態調整層級。若總紋理內存超限,自動降低非關鍵紋理的 Mip 層級(如將MipLevelideal強制偏移 +1)。
具體示例:開放世界地形紋理流送
假設場景中存在 2048x2048 的地形紋理(Mip 0-11 級),攝像機由近及遠移動:
-
?近距離階段?
- 計算得
MipLevelideal=2(512x512),加載 Mip 1-3 級。 - 顯存占用:
5122 + 2562 + 10242(約 1.75MB)。
- 計算得
-
?中距離階段?
- 攝像機拉遠,
MipLevelideal變為 5(64x64),卸載 Mip 1-3,加載 Mip 4-6。 - 顯存降至
642 + 322 + 1282(約 24KB)。
- 攝像機拉遠,
-
?突發情況處理?
若攝像機快速切近,通過
Texture.streamingMipmapPriority提高優先級,強制預加載 Mip 0-2 級以避免卡頓。
關鍵 API 與配置
-
?紋理設置?:在 Inspector 中啟用
Streaming Mip Maps并設置Mip Map Priority(默認 0,范圍 -128 到 127)。 -
?代碼控制?:
csharp // 強制某紋理使用 Mip 5 級 Texture2D tex = GetComponent<Renderer>().material.mainTexture as Texture2D; tex.streamingMipmaps = true; tex.RequestMipLevel(5);// 異步加載 -
?攝像機覆蓋?:通過
Streaming Controller組件設置Mipmap Bias,全局偏移所有紋理的MipLevelideal(如 +2 級以降低畫質)
紋理金字塔的共享機制
Unity 的紋理金字塔(Mipmap 層級)是?基于紋理資源本身維護的?,而非每個物體單獨維護。所有使用同一紋理的物體共享同一套紋理金字塔數據,運行時根據物體的屏幕空間覆蓋率和攝像機距離動態激活所需的 Mip 層級。
?資源級管理?
- 每個導入的紋理(如 2048x2048 的 PNG)在 Unity 中生成獨立的 Mipmap 金字塔(14 個層級)。這些層級存儲在磁盤和內存中,作為紋理資源的固有屬性,而非物體屬性。
?動態層級激活?
- GPU 通過
DDX/DDY計算當前像素的 UV 變化率,推導出適合的 Mip 層級(如遠距離物體使用 Mip 5 級)。 - Unity 的 Mipmap Streaming 系統僅加載當前需要的層級(如 Mip 4-6),其他層級保留在磁盤或按需異步加載。
?顯存優化?
- 多個物體共享同一紋理時,顯存中僅存儲該紋理的激活層級。例如:
- 物體 A 和 B 使用紋理
Tex_01,當前需 Mip 3 級,顯存僅保留 512x512 版本。 - 物體 C 使用同一紋理但需 Mip 5 級,系統復用已有金字塔數據,無需重復加載。
- 物體 A 和 B 使用紋理
示例場景分析
假設場景中有 100 個巖石模型共用同一 4K 紋理:
- ?未啟用 Streaming?:所有 14 個 Mip 層級(總計約 5.3MB)加載到顯存,無論物體遠近。
- ?啟用 Streaming?:
- 近處巖石使用 Mip 2(1024x1024),遠處使用 Mip 6(256x256)。
- 顯存僅保留 Mip 2-4 和 Mip 5-7,其他層級卸載,總占用降至 1.2MB。
性能影響與配置
- ?全局控制參數?:
QualitySettings.streamingMipmapsMemoryBudget限制所有紋理的流送內存總和,超限時自動降低非關鍵紋理的層級。 - ?優先級設置?:通過
Texture.mipMapPriority調整紋理加載順序,確保重要紋理(如角色貼圖)優先獲取高精度層級。
這種設計避免了重復資源存儲,同時通過動態流送優化顯存和帶寬
使用場景與限制
適用場景
- ?開放世界或大場景?:遠處物體自動使用低分辨率 Mip 層級,減少不必要的細節加載。
- ?移動端項目?:顯存和帶寬受限的設備(如 Unity 測試案例中的 HUAWEI P30)。
- ?高分辨率紋理?:如 4K/8K 紋理,傳統全加載方式顯存消耗過大。
限制
- ?內存額外開銷?:需存儲所有 Mip 層級到磁盤,占用約 33% 額外空間。
- ?加載延遲風險?:動態流送可能導致遠處物體短暫顯示低清紋理(需優化加載優先級)。
- ?UI 紋理不適用?:UI 元素通常需保持高清,關閉 Mipmap 更高效。
具體示例與實現
示例 1:基礎配置
在 Unity URP 中啟用 Mipmap Streaming:
- ?紋理導入設置?:勾選
Generate Mip Maps和Streaming Mipmaps,設置Mip Map Priority(優先級越高越早加載)。 - ?代碼控制?:通過
Texture.streamingMipmapsAPI 動態啟用/禁用流送。
示例 2:性能對比
- ?未啟用 Streaming?:2048x2048 紋理加載所有 12 個 Mip 層級(顯存占用約 5.3MB)。
- ?啟用 Streaming?:僅加載 Mip 10(512x512)時顯存占用降至 0.8MB,隨距離變化動態加載其他層級。
總結
Mipmap Streaming 通過動態管理紋理金字塔,平衡了顯存占用與渲染質量,是 URP 管線中優化大規模場景的關鍵技術。其核心優勢在于按需加載,但需注意磁盤空間和加載延遲的權衡
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,??)

摘要: Unity URP的紋理流送技術通過動態加載紋理的Mipmap層級優化顯存使用。傳統Mipmap會預加載所有層級(占用顯存為原始紋理的4/3倍),而流送技術根據物體與攝像機的距離,僅加載當前所需的層級,其他層級按需異步加載。GPU通過DDX/DDY計算UV變化率確定采樣層級,Unity維護紋理金字塔(14個層級)并動態管理顯存。該技術顯著降低顯存占用和帶寬壓力,消除遠距離物體的摩爾紋,適用于開放世界和移動端項目,但需注意額外磁盤空間和加載延遲問題。
浙公網安備 33010602011771號