【URP】Unity[法線貼圖]原理與實踐
【從UnityURP開始探索游戲渲染】專欄-直達
法線貼圖(Normal Mapping)是一種通過修改表面法線方向來模擬凹凸細節的紋理技術,無需增加模型幾何復雜度,顯著提升渲染效率同時保持視覺真實感。
解決的問題
- ?性能優化?:用低多邊形模型配合法線貼圖替代高模,減少計算開銷
- ?細節增強?:通過RGB通道存儲法線方向,模擬表面凹凸、劃痕等微觀結構
- ?動態光照響應?:每個像素的法線獨立參與光照計算,實現更真實的明暗變化
歷史發展節點
- ?1998年?:首次由Crytek在游戲《Far Cry》中大規模應用
- ?2004年?:成為DirectX 9標準特性,進入主流游戲引擎
- ?2018年?:Unity URP管線整合法線貼圖標準化工作流,支持移動端優化
- ?2022年?:HLSL語法改進,分離紋理對象與采樣器聲明
生成與使用流程
生成方法
- ?高模烘焙?:通過ZBrush等工具將高模細節烘焙到低模法線貼圖
- ?程序生成?:Substance Designer等工具從高度圖轉換生成
- ?手動繪制?:Photoshop使用濾鏡生成基礎法線紋理
詳細存儲原理參看了解具體如何計算和存儲的。
URP實現步驟
- ?紋理導入?
- 類型設為
Default,勾選Bump Map自動切換模式 - 壓縮格式推薦
BC5 (DXT5nm)或BC7
- 類型設為
- ?材質配置
- Shader選擇:URP > Lit 或 Simple Lit
法線貼圖拖拽至Normal Map插槽
調整Normal Scale參數控制凹凸強度(0.5-1.5為常用范圍?
- Shader選擇:URP > Lit 或 Simple Lit
- ?Shader核心原理?
- ?切線空間轉換?:通過TBN矩陣將法線從切線空間轉到世界空間
- ?光照計算?:轉換后的法線與光源方向點積決定漫反射強度
完整示例代碼
以下URP Shader實現法線貼圖與基礎光照:
-
?頂點著色器?:計算世界空間法線和切線
-
?片段著色器?:采樣法線貼圖并通過TBN矩陣轉換
-
?光照模型?:采用Lambert漫反射計算
-
NormalMapShader.shader
Shader "Custom/NormalMapShader" { Properties { _MainTex("Albedo", 2D) = "white" {} _NormalMap("Normal Map", 2D) = "bump" {} _NormalScale("Normal Scale", Range(0,2)) = 1 } SubShader { Tags { "RenderPipeline"="UniversalPipeline" } HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" ENDHLSL Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float3 normalWS : TEXCOORD1; float4 tangentWS : TEXCOORD2; }; sampler2D _MainTex; sampler2D _NormalMap; float _NormalScale; Varyings vert(Attributes IN) { Varyings OUT; VertexPositionInputs posInput = GetVertexPositionInputs(IN.positionOS.xyz); OUT.positionCS = posInput.positionCS; OUT.uv = IN.uv; VertexNormalInputs normInput = GetVertexNormalInputs(IN.normalOS, IN.tangentOS); OUT.normalWS = normInput.normalWS; OUT.tangentWS = float4(normInput.tangentWS, IN.tangentOS.w); return OUT; } half4 frag(Varyings IN) : SV_Target { float4 normalSample = tex2D(_NormalMap, IN.uv); float3 tangentNormal = UnpackNormalScale(normalSample, _NormalScale); float3 normalWS = IN.normalWS; float3 tangentWS = IN.tangentWS.xyz; float3 bitangentWS = cross(normalWS, tangentWS) * IN.tangentWS.w; float3x3 TBN = float3x3(tangentWS, bitangentWS, normalWS); float3 finalNormal = mul(tangentNormal, TBN); Light mainLight = GetMainLight(); float NdotL = saturate(dot(finalNormal, mainLight.direction)); half3 albedo = tex2D(_MainTex, IN.uv).rgb; half3 diffuse = albedo * NdotL * mainLight.color; return half4(diffuse, 1); } ENDHLSL } } }
數據結構定義
- Attributes結構體:聲明頂點輸入數據
- positionOS:模型空間頂點位置
- uv:紋理坐標
- normalOS:模型空間法線
- tangentOS:模型空間切線(含手性信息)
- Varyings結構體:定義頂點到片段的傳遞數據
- positionCS:裁剪空間位置
- normalWS:世界空間法線(通過URP內置函數轉換)
- tangentWS:世界空間切線(保留手性分量)
頂點著色器實現
- 核心流程:
- 調用GetVertexPositionInputs轉換模型空間到裁剪空間
- 通過GetVertexNormalInputs計算世界空間法線和切線
- 保持原始UV坐標傳遞
片段著色器實現
- 法線貼圖處理:
- float4 normalSample = tex2D(_NormalMap, IN.uv); float3 tangentNormal = UnpackNormalScale(normalSample, _NormalScale);
- 使用UnpackNormalScale函數解壓法線貼圖(范圍從[0,1]映射到[-1,1])并應用強度參數。
- TBN矩陣構建:
- float3x3 TBN = float3x3(tangentWS, bitangentWS, normalWS); float3 finalNormal = mul(tangentNormal, TBN);
- 通過切向量、副法線和法線構建正交基,將切線空間法線轉換到世界空間。
光照計算:
- Light mainLight = GetMainLight(); float NdotL = saturate(dot(finalNormal, mainLight.direction)); half3 diffuse = albedo * NdotL * mainLight.color;
- 采用Lambert漫反射模型,計算法線與光源方向的點積作為光照強度因子。
關鍵函數說明
- GetVertexPositionInputs:URP內置函數,處理頂點位置變換
- UnpackNormalScale:URP提供的法線貼圖解壓函數
- GetMainLight:獲取場景主光源信息(需配合URP的Lightweight Render Pipeline使用)
小結
- 坐標空間轉換:完整實現模型空間→世界空間→切線空間的轉換鏈
- 光照模型:基于物理的簡單漫反射計算
- 性能優化:使用half類型減少內存占用,適合移動端
- 擴展性:通過_NormalScale參數可動態調整法線貼圖強度
實際項目應用
- ?角色模型?:增強皮膚皺紋或服裝褶皺細節
- ?環境場景?:表現磚墻縫隙或金屬表面劃痕
- ?性能權衡?:移動端建議使用
Simple Lit簡化版著色器
關鍵注意事項:
- 確保模型具有正確的UV和切線數據
- 避免sRGB模式導入法線貼圖
- 多光源場景需在Shader中添加額外光照循環
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,??)

法線貼圖(Normal Mapping)是一種通過修改表面法線方向來模擬凹凸細節的紋理技術,無需增加模型幾何復雜度,顯著提升渲染效率同時保持視覺真實感。 解決的問題 ?性能優化?:用低多邊形模型配合法
浙公網安備 33010602011771號