【URP】Unity中Mipmap是如何實(shí)現(xiàn)的?
【從UnityURP開(kāi)始探索游戲渲染】專欄-直達(dá)
MipMap是Unity中用于優(yōu)化紋理渲染的多級(jí)漸遠(yuǎn)紋理技術(shù),其核心原理是通過(guò)預(yù)生成一系列分辨率遞減的紋理金字塔(從原始尺寸逐級(jí)減半至1×1像素),根據(jù)物體與攝像機(jī)的距離動(dòng)態(tài)選擇合適層級(jí)的紋理進(jìn)行采樣。在URP(Universal Render Pipeline)中,該技術(shù)通過(guò)減少遠(yuǎn)處物體的紋理細(xì)節(jié)來(lái)提升渲染效率,同時(shí)避免因紋理縮小導(dǎo)致的摩爾紋和鋸齒現(xiàn)象。
原理詳解
?紋理金字塔構(gòu)建?:
- 原始紋理經(jīng)過(guò)濾波處理生成多級(jí)縮略圖,例如256×256的紋理會(huì)生成128×128、64×64等層級(jí),每級(jí)分辨率遞減50%。
?動(dòng)態(tài)層級(jí)選擇?:
- GPU根據(jù)像素在屏幕空間中的覆蓋面積自動(dòng)計(jì)算合適的Mip層級(jí)(公式為
level = log2(max(ddx,ddy)),其中ddx/ddy為紋理坐標(biāo)導(dǎo)數(shù))。
?過(guò)濾技術(shù)配合?:
- ?雙線性過(guò)濾?:在單一Mip層級(jí)內(nèi)插值。
- ?三線性過(guò)濾?:在相鄰兩個(gè)Mip層級(jí)間插值,消除層級(jí)切換的突兀感。
構(gòu)建 紋理金字塔
在Unity URP中,Mipmap紋理金字塔的構(gòu)建是通過(guò)GPU逐級(jí)下采樣實(shí)現(xiàn)的,其核心流程分為硬件自動(dòng)生成和計(jì)算著色器手動(dòng)生成兩種方式。
硬件自動(dòng)生成原理
- ?基礎(chǔ)紋理處理?:原始紋理(如2048×2048)經(jīng)過(guò)雙線性/三線性濾波處理,生成分辨率逐級(jí)減半的子紋理(1024×1024、512×512等),直至1×1像素。
- ?層級(jí)關(guān)系計(jì)算?:GPU根據(jù)屏幕像素覆蓋率自動(dòng)選擇Mip層級(jí),公式為:$lod=log2(max(\frac{\partial u}{\partial x},\frac{\partial v}{\partial y}))$其中偏導(dǎo)數(shù)通過(guò)紋理坐標(biāo)微分計(jì)算。
計(jì)算著色器手動(dòng)生成示例(Hi-Z技術(shù))
- 通過(guò)Compute Shader構(gòu)建深度紋理的金字塔:
-
HiZFeature.cs
using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class HiZFeature : ScriptableRendererFeature { class HiZPass : ScriptableRenderPass { ComputeShader _hizShader; RenderTexture _hizPyramid; public override void Execute(ScriptableRenderContext context, ref RenderingData data) { CommandBuffer cmd = CommandBufferPool.Get(); // 從深度紋理生成Mipmap金字塔 int width = _hizPyramid.width; int height = _hizPyramid.height; for (int mip = 0; width >= 8 || height >= 8; mip++) { cmd.SetComputeTextureParam(_hizShader, 0, "_HiZTexture", _hizPyramid, mip); cmd.DispatchCompute(_hizShader, 0, width/8, height/8, 1); width >>= 1; height >>= 1; } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } } } -
HiZ.compute
#pragma kernel CSMain_HiZ Texture2D<float> _DepthTexture; RWTexture2D<float> _HiZTexture; [numthreads(8, 8, 1)] void CSMain_HiZ(uint3 id : SV_DispatchThreadID) { // 8x8區(qū)域取最大深度值作為下采樣結(jié)果 float maxDepth = 0; for (int x = 0; x < 8; x++) { for (int y = 0; y < 8; y++) { maxDepth = max(maxDepth, _DepthTexture[id.xy * 8 + uint2(x,y)]); } } _HiZTexture[id.xy] = maxDepth; }
-
關(guān)鍵步驟解析
- ?層級(jí)生成邏輯?:每級(jí)Mipmap通過(guò)對(duì)上一級(jí)4個(gè)像素取平均值(顏色紋理)或最大值(深度紋理)生成,例如256×256紋理生成128×128層級(jí)時(shí),每個(gè)新像素由原紋理2×2區(qū)域計(jì)算得出。
- ?過(guò)濾模式影響?:
- ?雙線性過(guò)濾?:在單層Mip內(nèi)插值4個(gè)相鄰紋素。
- ?三線性過(guò)濾?:在相鄰兩層Mip間進(jìn)行二次插值,消除層級(jí)切換突變。
應(yīng)用場(chǎng)景對(duì)比
| 生成方式 | 適用場(chǎng)景 | 性能開(kāi)銷 |
|---|---|---|
| 硬件自動(dòng)生成 | 常規(guī)顏色紋理 | 低 |
| 計(jì)算著色器生成 | 深度紋理/特殊效果(如Hi-Z) | 中高 |
通過(guò)調(diào)整RenderTexture.useMipMap屬性和GenerateMipMaps標(biāo)志位可控制生成行為。手動(dòng)生成更適合需要自定義下采樣規(guī)則的場(chǎng)景,如遮擋剔除優(yōu)化.
實(shí)現(xiàn)動(dòng)態(tài)層級(jí)選擇
在Unity URP中,Mipmap的動(dòng)態(tài)層級(jí)選擇是通過(guò)GPU硬件自動(dòng)計(jì)算紋理坐標(biāo)的導(dǎo)數(shù)(ddx/ddy)實(shí)現(xiàn)的.
動(dòng)態(tài)選擇原理
-
?導(dǎo)數(shù)計(jì)算?$lod=log2(max(∥\frac{\partial u}{\partial x}∥,∥\frac{\partial v}{\partial y}∥))$
GPU通過(guò)片元著色器中的紋理坐標(biāo)偏導(dǎo)數(shù)(
ddx(uv)和ddy(uv))確定屏幕像素覆蓋的紋理區(qū)域大小。當(dāng)物體距離攝像機(jī)越遠(yuǎn),UV坐標(biāo)變化率越大,導(dǎo)數(shù)值越高。示例:若屏幕像素覆蓋4×4紋素區(qū)域,則Mip層級(jí)計(jì)算公式為:
此時(shí)計(jì)算結(jié)果為2(因4=22),選擇Mip Level 2的紋理。
-
?層級(jí)插值?
啟用三線性過(guò)濾時(shí),GPU會(huì)在計(jì)算出的層級(jí)(如2.3級(jí))相鄰兩層(Level 2和Level 3)之間進(jìn)行插值,消除突變感。
-
?LOD偏移控制?
URP通過(guò)
Texture2D.mipMapBias參數(shù)手動(dòng)調(diào)整層級(jí)偏移,正值使紋理更模糊(強(qiáng)制使用更高層級(jí)),負(fù)值保留細(xì)節(jié)(偏向低級(jí))。
實(shí)現(xiàn)示例
以下Shader代碼演示手動(dòng)控制Mip層級(jí)的兩種方式:
hlsl
// 方式1:通過(guò)tex2Dlod硬編碼層級(jí)
fixed4 frag(v2f i) : SV_Target {
float4 uv = float4(i.uv, 0, _ManualLod); // _ManualLod為自定義層級(jí)
return tex2Dlod(_MainTex, uv);
}
// 方式2:根據(jù)距離動(dòng)態(tài)計(jì)算層級(jí)
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
float dist = distance(_WorldSpaceCameraPos, worldPos);
float lod = log2(dist * _LodScale); // _LodScale控制距離敏感度
fixed4 col = tex2Dlod(_MainTex, float4(i.uv, 0, lod));
層級(jí)選擇優(yōu)化
-
?Hi-Z技術(shù)?
對(duì)深度紋理構(gòu)建Mip金字塔時(shí),每層級(jí)存儲(chǔ)最大深度值(而非顏色平均值),加速遮擋剔除。
流程:
- 生成深度紋理Mipmap時(shí),通過(guò)Compute Shader對(duì)4×4區(qū)域取最大值下采樣。
- 渲染時(shí)根據(jù)層級(jí)深度快速判斷可見(jiàn)性。
-
?ShaderGraph節(jié)點(diǎn)?
URP的
Calculate Level Of Detail節(jié)點(diǎn)提供兩種模式:- ?Clamped?:限制在紋理最大層級(jí)內(nèi),避免越界。
- ?Unclamped?:允許超出現(xiàn)有層級(jí),需配合邊界處理。
性能與質(zhì)量平衡
- ?過(guò)模糊問(wèn)題?:通過(guò)
QualitySettings.masterTextureLimit全局限制最高層級(jí)。 - ?銳化需求?:禁用Mipmap或使用
UnlitShader避免自動(dòng)插值。
典型應(yīng)用場(chǎng)景包括地形渲染(遠(yuǎn)山使用高M(jìn)ip層級(jí))和動(dòng)態(tài)LOD系統(tǒng)(根據(jù)物體重要性調(diào)整mipMapBias)
解決的問(wèn)題
?性能優(yōu)化?:
- 減少顯存帶寬占用,遠(yuǎn)處物體使用低分辨率紋理降低GPU負(fù)載。
?視覺(jué)質(zhì)量?:
- 消除遠(yuǎn)景的像素閃爍(Texture Aliasing)和鋸齒,提升平滑度。
?緩存命中率?:
- 低分辨率紋理占用更少緩存空間,提高采樣效率。
使用場(chǎng)景與限制
- ?適用場(chǎng)景?:
- 3D開(kāi)放世界地形(如遠(yuǎn)山、建筑)。
- 動(dòng)態(tài)縮放的物體(如角色模型在遠(yuǎn)距離時(shí))。
- ?不適用場(chǎng)景?:
- 2D像素游戲(需保持銳利像素風(fēng)格)。
- UI元素(通常無(wú)需動(dòng)態(tài)縮放)。
- ?限制?:
- 內(nèi)存開(kāi)銷增加33%(存儲(chǔ)多級(jí)紋理)。
- 可能引起遠(yuǎn)處紋理過(guò)度模糊(需調(diào)整Mip Bias參數(shù))。
具體示例
-
?Shader實(shí)現(xiàn)?:
在URP Shader中,可通過(guò)
tex2Dlod函數(shù)手動(dòng)指定Mip層級(jí)(float4參數(shù)的w分量控制層級(jí))。例如:hlsl fixed4 frag(v2f i) : SV_Target { return tex2Dlod(_MainTex, float4(i.uv, 0, _MipLevel)); }調(diào)整
_MipLevel可觀察不同層級(jí)的模糊效果. -
?Unity編輯器演示?:
- 導(dǎo)入紋理后勾選
Generate Mip Maps,觀察Inspector面板中的Mipmap預(yù)覽滑塊(0-10級(jí))。 - 對(duì)比開(kāi)啟/關(guān)閉Mipmap的相同紋理,遠(yuǎn)處物體在開(kāi)啟時(shí)會(huì)自然模糊,關(guān)閉則出現(xiàn)像素噪點(diǎn)。
- 導(dǎo)入紋理后勾選
通過(guò)權(quán)衡內(nèi)存與性能,Mipmap在URP中成為優(yōu)化大規(guī)模場(chǎng)景渲染的關(guān)鍵技術(shù)之一
【從UnityURP開(kāi)始探索游戲渲染】專欄-直達(dá)
(歡迎點(diǎn)贊留言探討,更多人加入進(jìn)來(lái)能更加完善這個(gè)探索的過(guò)程,??)

《Unity URP中的MipMap技術(shù)解析》摘要:本文詳解Unity URP管線中的MipMap多級(jí)漸遠(yuǎn)紋理技術(shù),通過(guò)預(yù)生成分辨率遞減的紋理金字塔(如256×256→128×128→...→1×1),根據(jù)物體距離動(dòng)態(tài)選擇紋理層級(jí)。重點(diǎn)闡述:1)硬件自動(dòng)生成與計(jì)算著色器手動(dòng)生成兩種構(gòu)建方式;2)基于紋理坐標(biāo)導(dǎo)數(shù)的動(dòng)態(tài)層級(jí)選擇算法;3)三線性過(guò)濾消除層級(jí)突變。該技術(shù)可優(yōu)化顯存帶寬、提升緩存命中率,有效解決遠(yuǎn)景鋸齒問(wèn)題,適用于3D開(kāi)放世界等場(chǎng)景,但會(huì)增加33%內(nèi)存開(kāi)銷。文中包含Hi-Z深度金字塔等實(shí)用案例代碼,
浙公網(wǎng)安備 33010602011771號(hào)