【從UnityURP開始探索遊戲渲染】專欄-直達
URP內置Unlit Shader的作用與原理
Unlit Shader是Unity通用渲染管線(URP)中的基礎着色器,主要用於渲染不受光照影響的物體。其核心原理是通過直接採樣紋理或顏色值輸出到屏幕,跳過了複雜的光照計算流程。這種着色器特別適合UI元素、粒子特效、全息投影等需要保持恆定亮度的場景,因為它的渲染結果不會隨光照環境變化而改變。
在URP架構中,Unlit Shader通過ShaderLab語法定義,內部使用HLSL編寫核心邏輯。與Built-in管線相比,URP版本優化了渲染流程,包含三個關鍵Pass:主繪製Pass、深度Only Pass和元數據Pass(用於光照烘焙)。其核心特點是:
- 無光照計算:直接輸出Albedo顏色或紋理採樣結果
- 支持Alpha混合:可實現透明效果
- 移動端優化:減少了GPU指令數量
發展歷史演變
Unlit Shader隨着Unity渲染管線的演進經歷了三個階段:
- Built-in管線時期(2012-2018):最初作為簡單着色器出現在標準資源包中,使用CG語言編寫,功能較為基礎
- LWRP過渡期(2018-2020):輕量級渲染管線中首次針對移動平台優化,引入HLSL替代CG
- URP成熟期(2020至今):成為Universal RP的核心組件,支持Shader Graph可視化編程,並優化了多Pass協作機制
具體使用示例
創建Unlit材質的基本步驟:
- 在Project窗口右鍵創建Material
- 材質Inspector中選擇Shader路徑:"Universal Render Pipeline/Unlit"
-
配置基礎屬性:
- Base Map:主紋理貼圖
- Base Color:色調疊加
- Alpha:透明度控制
代碼説明:
- 定義包含紋理和顏色屬性的基礎Unlit Shader
- 使用URP核心庫中的TransformObjectToHClip方法進行座標轉換
- 片元着色器直接返回紋理採樣結果與顏色的乘積
-
UnlitExample.shader
Shader "Custom/UnlitTexture" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Color", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; float4 _Color; Varyings vert(Attributes IN) { Varyings OUT; OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz); OUT.uv = IN.uv; return OUT; } half4 frag(Varyings IN) : SV_Target { return tex2D(_MainTex, IN.uv) * _Color; } ENDHLSL } } } -
UnlitGraph.shadergraph
{ "m_Nodes": [ { "m_Id": "d4f5e3c7-1a2d-4b8f-a3e1-6c9b8d2e1f0a", "m_Type": "UnityEditor.ShaderGraph.Texture2DNode", "m_Position": { "x": -208, "y": -16 }, "m_Outputs": [ { "m_Id": "out" } ], "m_Texture": { "m_DefaultValue": {} } }, { "m_Id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6", "m_Type": "UnityEditor.ShaderGraph.ColorNode", "m_Position": { "x": -200, "y": 100 }, "m_Outputs": [ { "m_Id": "out" } ], "m_Color": { "r": 1, "g": 1, "b": 1, "a": 1 } }, { "m_Id": "b2c3d4e5-f6g7-8h9i-0j1k-l2m3n4o5p6q7", "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", "m_Position": { "x": 0, "y": 0 }, "m_Inputs": [ { "m_Id": "a", "m_SlotId": 0 }, { "m_Id": "b", "m_SlotId": 1 } ], "m_Outputs": [ { "m_Id": "out" } ] } ], "m_Edges": [ { "m_OutputSlot": "d4f5e3c7-1a2d-4b8f-a3e1-6c9b8d2e1f0a.out", "m_InputSlot": "b2c3d4e5-f6g7-8h9i-0j1k-l2m3n4o5p6q7.a" }, { "m_OutputSlot": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6.out", "m_InputSlot": "b2c3d4e5-f6g7-8h9i-0j1k-l2m3n4o5p6q7.b" } ] }
Shader Graph應用示例
在Shader Graph中創建Unlit效果的步驟:
- 創建新的Shader Graph文件(右鍵 > Create > Shader > Universal Render Pipeline > Unlit Shader Graph)
-
核心節點配置:
- 添加Sample Texture 2D節點作為基礎紋理輸入
- 連接Color參數節點實現色調控制
- 使用Multiply節點混合紋理和顏色
-
高級功能擴展:
- 添加Time節點驅動UV動畫
- 通過Vertex Position節點實現頂點變形
代碼説明:
- 構建包含紋理採樣和顏色混合的基礎Unlit着色器
- 通過節點連接實現材質屬性的可視化編輯
- 可擴展添加UV滾動、頂點動畫等高級效果
-
UnlitExample.shader
Shader "Custom/UnlitTexture" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Color", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; float4 _Color; Varyings vert(Attributes IN) { Varyings OUT; OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz); OUT.uv = IN.uv; return OUT; } half4 frag(Varyings IN) : SV_Target { return tex2D(_MainTex, IN.uv) * _Color; } ENDHLSL } } } -
UnlitGraph.shadergraph
{ "m_Nodes": [ { "m_Id": "d4f5e3c7-1a2d-4b8f-a3e1-6c9b8d2e1f0a", "m_Type": "UnityEditor.ShaderGraph.Texture2DNode", "m_Position": { "x": -208, "y": -16 }, "m_Outputs": [ { "m_Id": "out" } ], "m_Texture": { "m_DefaultValue": {} } }, { "m_Id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6", "m_Type": "UnityEditor.ShaderGraph.ColorNode", "m_Position": { "x": -200, "y": 100 }, "m_Outputs": [ { "m_Id": "out" } ], "m_Color": { "r": 1, "g": 1, "b": 1, "a": 1 } }, { "m_Id": "b2c3d4e5-f6g7-8h9i-0j1k-l2m3n4o5p6q7", "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", "m_Position": { "x": 0, "y": 0 }, "m_Inputs": [ { "m_Id": "a", "m_SlotId": 0 }, { "m_Id": "b", "m_SlotId": 1 } ], "m_Outputs": [ { "m_Id": "out" } ] } ], "m_Edges": [ { "m_OutputSlot": "d4f5e3c7-1a2d-4b8f-a3e1-6c9b8d2e1f0a.out", "m_InputSlot": "b2c3d4e5-f6g7-8h9i-0j1k-l2m3n4o5p6q7.a" }, { "m_OutputSlot": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6.out", "m_InputSlot": "b2c3d4e5-f6g7-8h9i-0j1k-l2m3n4o5p6q7.b" } ] }
實際應用時可結合粒子系統創建發光軌跡,或為UI元素添加動態高亮效果。URP Unlit Shader的輕量級特性使其在移動設備上能保持60fps以上的渲染性能
典型應用場景及實現
光暈效果(Halo)
- 應用實例:角色技能特效、UI高亮提示。通過透明紋理實現邊緣發光,如1中描述的透明光暈材質。
-
實現步驟:
- 導入紋理並設置:
Texture Type為Default (sRGB),勾選Alpha Is Transparency,Wrap Mode設為Clamp。 - 創建材質:選擇
Universal Render Pipeline/UnlitShader,設置Surface Type為Transparent,拖拽紋理到Base Map插槽。 - 調整
Tint顏色控制光暈色彩。
- 導入紋理並設置:
全息投影效果
- 應用實例:科幻場景中的虛擬角色或界面。結合透明度與掃描線紋理。
-
實現步驟:
- 使用
UnlitShader並啓用透明混合(Blend SrcAlpha OneMinusSrcAlpha)。 - 添加頂點偏移代碼模擬全息抖動,通過
_Time變量控制動態效果。 - 疊加掃描線紋理(如
_HologramLine1)和菲涅爾反射增強立體感。
- 使用
透明遮罩(如塑料薄膜)
- 應用實例:UI遮罩或半透明裝飾物。通過Alpha通道控制透明度,如中的塑料薄膜材質。
-
實現步驟:
- 在圖片編輯器中創建帶Alpha通道的紋理,白色區域不透明,灰色區域半透明。
- 材質Shader選擇
Unlit,設置Transparent模式,紋理綁定到Base Map。
發光廣告牌(Billboard)
- 應用實例:遊戲內固定亮度標識或霓虹燈。直接顯示紋理顏色不受光照影響。
-
實現步驟:
- 使用
UnlitShader,Surface Type設為Opaque。 - 通過
Base Map設置發光紋理,調整Tint顏色增強亮度。
- 使用
景深遮擋標記
- 應用實例:半透明物體深度寫入(如玻璃瓶),解決景深效果失效問題。
-
實現步驟:
- 創建兩個材質:一個透明材質(
Queue=Transparent),一個深度寫入材質(Queue=2000)。 - 深度寫入材質使用
UnlitShader並啓用ZWrite On。
- 創建兩個材質:一個透明材質(
關鍵注意事項
- 渲染順序:透明物體需關閉深度寫入(
ZWrite Off),併合理設置Queue標籤避免混合錯誤。 - 性能優化:複雜效果(如全息投影)建議結合頂點着色器計算,減少片元着色器負擔
【從UnityURP開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)