【從UnityURP開始探索遊戲渲染】專欄-直達
SimpleLit Shader的作用與原理
SimpleLit Shader是Unity通用渲染管線(URP)中的一種輕量級着色器,主要用於低端設備或需要高效渲染的場景。它採用簡化的Blinn-Phong光照模型,不計算物理正確性和能量守恆,從而實現了比標準Lit Shader更快的渲染速度。
核心原理
- 簡化光照模型:使用Blinn-Phong模型而非PBR,省略了複雜的物理計算
- 模塊化結構:分為Surface Options(控制渲染方式)、Surface Inputs(描述表面特性)和Advanced Options(底層渲染設置)三部分
- 前向渲染路徑:通過"UniversalForward" Pass實現,支持主光源陰影和附加光源計算
- 變體控制:通過Shader Feature和Multi Compile指令管理不同功能組合,減少不必要的變體
發展歷史
SimpleLit Shader隨着URP的發展經歷了多個版本迭代:
- 早期版本(2019-2020):作為URP首批內置Shader之一,提供基礎光照功能
- URP 7.x時期(2021):優化了變體管理,增加了GPU實例化支持
- URP 12.1.1(2022):完善了SubShader錯誤處理,默認返回紫色洋葱效果
- 當前版本(2024-2025):支持DOTS Instancing,增強了與Shader Graph的兼容性
具體使用方法
基礎應用示例
- 創建材質:在Project窗口右鍵 > Create > Material
- 選擇Shader:在材質Inspector中,選擇"Universal Render Pipeline > Simple Lit"
-
配置屬性:
- Base Map:設置基礎顏色紋理
- Base Color:調整整體色調
- Smoothness:控制表面光滑度
- Emission:添加自發光效果
代碼示例
csharp
// 通過代碼設置SimpleLit材質屬性
Material simpleLitMat = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));
simpleLitMat.SetTexture("_BaseMap", Resources.Load<Texture>("BaseTexture"));
simpleLitMat.SetColor("_BaseColor", Color.blue);
simpleLitMat.SetFloat("_Smoothness", 0.75f);
Shader Graph中的應用
創建SimpleLit風格Shader
- 創建新Graph:右鍵 > Create > Shader > Universal Render Pipeline > Blank Shader Graph
-
設置Graph設置:
- Material設置為"Simple Lit"
- Surface設置為"Opaque"或"Transparent"
-
構建節點網絡:
- 使用"Sample Texture 2D"節點獲取基礎顏色
- 通過"Normal From Texture"節點處理法線貼圖
- 連接"Master Stack"的對應輸入端口
示例Graph功能
-
基礎顏色混合:
- 混合紋理採樣和顏色參數
- 添加細節遮罩控制混合強度
-
動態高光控制:
- 使用時間節點驅動高光強度變化
- 通過頂點位置影響高光範圍
-
邊緣發光效果:
- 計算視角與法線夾角
- 使用Fresnel節點創建邊緣光
保存與應用
- 保存Graph後生成.shadergraph文件
- 創建材質並選擇生成的Shader
- 通過材質參數面板調整公開屬性
Shader simple lit 對比 Lit
SimpleLit Shader與Lit Shader的性能差異主要體現在光照模型的計算複雜度上。SimpleLit採用簡化的Blinn-Phong光照模型,而Lit基於物理渲染(PBR),兩者的性能差距和適用場景如下:
性能對比
-
渲染效率
SimpleLit通過忽略物理正確性和能量守恆計算,相比Lit Shader可提升約30%-50%的渲染性能,尤其在低端移動設備上表現更顯著。Lit Shader因需計算微表面模型(GGX+Smith)和複雜的光照交互,對GPU負擔較大。
-
變體複雜度
Lit Shader支持更多材質屬性(如金屬度、粗糙度),導致Shader變體數量遠高於SimpleLit,增加了內存和編譯開銷。SimpleLit的變體更少,適合需要快速迭代或大量實例化的場景。
材質實現能力
-
SimpleLit適用材質
- 卡通風格表面(非PBR)
- 低多邊形(Low Poly)美術風格
- 需要快速渲染的靜態物體或背景元素
- 通過調整
_SpecColor和_Glossiness實現簡單高光效果,但不支持動態環境光遮蔽(AO)或複雜反射。
-
Lit適用材質
- 金屬/非金屬PBR材質(如真實感金屬、石材)
- 需要動態光照和陰影的高質量場景
- 支持屏幕空間全局光照(SSGI)等高級特性。
選擇建議
- 性能優先:選擇SimpleLit,尤其針對移動端或低端設備。
- 效果優先:需真實物理交互的場景(如角色、動態物體)使用Lit。
兩者均支持URP的GPU實例化和SRP Batcher優化,但SimpleLit在批量渲染時優勢更明顯.
卡通風格 非PBR 材質實現
核心實現原理
- 基礎光照模型:採用Simple Lit的Lambert漫反射+Blinn-Phong高光組合,通過閾值化處理實現色階分離
- 邊緣光增強:利用菲涅爾效應節點(Fresnel Effect Node)生成輪廓光,通過Power參數控制邊緣寬度
- 色塊分割:使用Step或SmoothStep函數對光照結果進行離散化處理,形成卡通風格的色塊過渡
關鍵參數説明
- _RampThreshold:控制陰影與亮部的分界閾值,值越小陰影區域越大
- _RampSmooth:色塊邊緣的平滑過渡範圍,設為0時產生硬邊緣
- _RimPower:調整邊緣光衰減速度,值越大輪廓線越細
-
ToonSimpleLit.shader
Shader "Universal Render Pipeline/Simple Toon" { Properties { _BaseColor("Base Color", Color) = (1,1,1,1) _BaseMap("Base Map", 2D) = "white" {} _ShadowColor("Shadow Color", Color) = (0.4,0.4,0.4,1) _RampThreshold("Ramp Threshold", Range(0,1)) = 0.5 _RampSmooth("Ramp Smooth", Range(0.01,0.1)) = 0.01 _SpecColor("Specular Color", Color) = (0.9,0.9,0.9,1) _SpecThreshold("Spec Threshold", Range(0,1)) = 0.5 _SpecSmooth("Spec Smooth", Range(0,0.1)) = 0.02 _RimPower("Rim Power", Range(0,10)) = 5 _RimColor("Rim Color", Color) = (0.8,0.8,0.8,1) } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" } HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); CBUFFER_START(UnityPerMaterial) float4 _BaseColor; float4 _BaseMap_ST; float4 _ShadowColor; float _RampThreshold; float _RampSmooth; float4 _SpecColor; float _SpecThreshold; float _SpecSmooth; float _RimPower; float4 _RimColor; CBUFFER_END struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float3 normalWS : TEXCOORD1; float3 viewDirWS : TEXCOORD2; float3 positionWS : TEXCOORD3; }; Varyings ToonPassVertex(Attributes input) { Varyings output; VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); output.positionCS = vertexInput.positionCS; output.uv = TRANSFORM_TEX(input.uv, _BaseMap); VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS); output.normalWS = normalInput.normalWS; output.viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS); output.positionWS = vertexInput.positionWS; return output; } half4 ToonPassFragment(Varyings input) : SV_Target { // 基礎紋理採樣 half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv); half3 baseColor = baseMap.rgb * _BaseColor.rgb; // 光照計算 Light mainLight = GetMainLight(); float3 lightDir = normalize(mainLight.direction); float3 normalWS = normalize(input.normalWS); float NdotL = dot(normalWS, lightDir); // 漫反射色階化 float diffuse = smoothstep(_RampThreshold - _RampSmooth, _RampThreshold + _RampSmooth, NdotL * 0.5 + 0.5); float3 diffuseColor = lerp(_ShadowColor.rgb, 1, diffuse) * baseColor; // 高光計算 float3 viewDir = normalize(input.viewDirWS); float3 halfDir = normalize(lightDir + viewDir); float specular = pow(max(0, dot(normalWS, halfDir)), 32); specular = smoothstep(_SpecThreshold - _SpecSmooth, _SpecThreshold + _SpecSmooth, specular); float3 specularColor = specular * _SpecColor.rgb * mainLight.color; // 邊緣光 float rim = 1 - max(0, dot(viewDir, normalWS)); rim = pow(rim, _RimPower); float3 rimColor = rim * _RimColor.rgb; // 最終合成 float3 finalColor = diffuseColor * mainLight.color + specularColor + rimColor; return half4(finalColor, baseMap.a); } ENDHLSL Pass { Name "ToonPass" Tags { "LightMode"="UniversalForward" } HLSLPROGRAM #pragma vertex ToonPassVertex #pragma fragment ToonPassFragment ENDHLSL } } }
擴展優化建議
- 添加色階貼圖:使用1D紋理控制光照過渡曲線,實現更復雜的卡通色階效果
- 描邊效果:通過背面擠出法或後處理實現輪廓描邊(需額外Pass)
- 材質變體:通過Shader變體支持不同風格切換(如賽璐璐/水彩風格)
該Shader保留了URP輕量級特性,通過HLSL重寫光照模型實現非PBR卡通效果,可直接在URP項目中使用。如需更復雜的藝術控制,可參考原神風格的貼圖通道分配方案
性能優化建議
- 變體控制:禁用不必要的Shader變體(如_SPECGLOSSMAP)減少內存佔用
- GPU Instancing:對相同材質的對象啓用實例化減少Draw Call
- 紋理壓縮:使用適當的壓縮格式減少顯存佔用
- LOD組合:與複雜Shader配合使用,根據距離切換SimpleLit
SimpleLit Shader通過簡化光照計算在保持基本視覺效果的同時顯著提升渲染效率,特別適合移動平台和低端設備,是URP管線中平衡性能與效果的重要工具
【從UnityURP開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)