博客 / 詳情

返回

【URP】Unity[內置Shader]非光照Unlit

【從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 TypeDefault (sRGB),勾選Alpha Is TransparencyWrap Mode設為Clamp
    • 創建材質:選擇Universal Render Pipeline/Unlit Shader,設置Surface TypeTransparent,拖拽紋理到Base Map插槽。
    • 調整Tint顏色控制光暈色彩。

全息投影效果

  • 應用實例‌:科幻場景中的虛擬角色或界面。結合透明度與掃描線紋理。
  • 實現步驟‌:

    • 使用Unlit Shader並啓用透明混合(Blend SrcAlpha OneMinusSrcAlpha)。
    • 添加頂點偏移代碼模擬全息抖動,通過_Time變量控制動態效果。
    • 疊加掃描線紋理(如_HologramLine1)和菲涅爾反射增強立體感。

透明遮罩(如塑料薄膜)

  • 應用實例‌:UI遮罩或半透明裝飾物。通過Alpha通道控制透明度,如中的塑料薄膜材質。
  • 實現步驟‌:

    • 在圖片編輯器中創建帶Alpha通道的紋理,白色區域不透明,灰色區域半透明。
    • 材質Shader選擇Unlit,設置Transparent模式,紋理綁定到Base Map

發光廣告牌(Billboard)

  • 應用實例‌:遊戲內固定亮度標識或霓虹燈。直接顯示紋理顏色不受光照影響。
  • 實現步驟‌:

    • 使用Unlit Shader,Surface Type設為Opaque
    • 通過Base Map設置發光紋理,調整Tint顏色增強亮度。

景深遮擋標記

  • 應用實例‌:半透明物體深度寫入(如玻璃瓶),解決景深效果失效問題。
  • 實現步驟‌:

    • 創建兩個材質:一個透明材質(Queue=Transparent),一個深度寫入材質(Queue=2000)。
    • 深度寫入材質使用Unlit Shader並啓用ZWrite On

關鍵注意事項

  • 渲染順序‌:透明物體需關閉深度寫入(ZWrite Off),併合理設置Queue標籤避免混合錯誤。
  • 性能優化‌:複雜效果(如全息投影)建議結合頂點着色器計算,減少片元着色器負擔

【從UnityURP開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.