Screen Space Shadows(屏幕空間陰影)是Unity URP中通過屏幕空間數據實時計算陰影的技術,其核心原理是通過深度/法線信息重建世界座標後與陰影貼圖比較生成陰影。以下是詳細分析:


Screen Space Shadows(屏幕空間陰影)是Unity URP中通過屏幕空間數據實時計算陰影的技術,其核心原理是通過深度/法線信息重建世界座標後與陰影貼圖比較生成陰影。以下是詳細分析:

技術原理與發展歷史

  • 基礎原理:傳統Shadow Mapping需從光源視角生成深度圖,再與攝像機視角深度比較。而Screen Space Shadows直接在屏幕空間計算,利用_CameraDepthTexture和_MainLightShadowmapTexture進行深度比較。
  • 技術演進
  • 早期採用標準Shadow Mapping存在精度問題
  • 引入級聯陰影(CSM)解決大場景問題
  • URP 14+版本通過ScreenSpaceShadowResolvePass實現優化
  • 性能對比:相比傳統方案,屏幕空間陰影減少Overdraw但增加Depth Prepass開銷。

原理

核心原理

  • 雙階段渲染機制
  • 深度圖生成階段:從光源視角渲染場景,將最近表面深度值存儲到_MainLightShadowmapTexture
  • 陰影判定階段:在攝像機視角渲染時,將像素座標轉換到光源空間,比較當前深度與ShadowMap中的深度值,若當前深度更大則判定為陰影區域
  • 級聯陰影優化CSM
    通過將視錐體劃分為多個層級(如4級),近處使用高分辨率ShadowMap,遠處使用低分辨率,平衡性能與精度

關鍵實現步驟

  • ShadowCaster Pass
hlsl
Pass {
    Tags {"LightMode"="ShadowCaster"}
    HLSLPROGRAM
    #pragma vertex ShadowPassVertex
    #pragma fragment ShadowPassFragment
    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    // 應用深度偏移防止自陰影偽影
    float3 _ShadowBias; // x:DepthBias, y:NormalBias
    ENDHLSL
}

該Pass專用於生成深度圖,通過_ShadowBias參數控制深度偏移

  • 光源空間矩陣計算
    構建_MainLightWorldToShadow矩陣,將世界座標轉換到光源裁剪空間:
csharp
Matrix4x4 worldToView = light.transform.worldToLocalMatrix;
Matrix4x4 viewToProj = GL.GetGPUProjectionMatrix(light.projectionMatrix, false);
_MainLightWorldToShadow = viewToProj * worldToView;

該矩陣用於在着色器中計算陰影座標

  • 陰影採樣與混合
    在片元着色器中通過PCF(Percentage Closer Filtering)實現軟陰影:
hlsl
float SampleShadowmap(float4 shadowCoord) {
    float shadow = 0;
    for(int i = 0; i < 4; i++) {
        shadow += SAMPLE_TEXTURE2D_SHADOW(
            _MainLightShadowmapTexture,
            sampler_MainLightShadowmapTexture,
            shadowCoord.xyz + poissonDisk[i] * _ShadowSoftness
        );
    }
    return shadow / 4;
}

使用泊松圓盤採樣實現邊緣柔化

完整URP示例

  • ShadowFeature.cs
using UnityEngine.Rendering.Universal;

public class ShadowFeature : ScriptableRendererFeature {
    class ShadowPass : ScriptableRenderPass {
        public override void Execute(ScriptableRenderContext context, ref RenderingData data) {
            // 1. 配置光源參數
            var shadowLight = data.lightData.mainLightIndex;
            if (shadowLight == -1) return;

            // 2. 渲染ShadowMap
            CommandBuffer cmd = CommandBufferPool.Get("ShadowMap");
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
    }
}
  • ShadowShader.shader
Shader "Custom/ShadowReceiver" {
    Properties {
        _ShadowStrength("Shadow Strength", Range(0,1)) = 0.5
    }
    SubShader {
        Pass {
            HLSLPROGRAM
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            float _ShadowStrength;

            float4 frag(v2f i) : SV_Target {
                float shadow = MainLightRealtimeShadow(i.shadowCoord);
                return lerp(1, shadow, _ShadowStrength);
            }
            ENDHLSL
        }
    }
}

參數説明

參數

作用

典型值

技術原理

Shadow Distance

陰影最大渲染距離

50-100

超出距離後淡出陰影

Cascade Count

級聯分層數

2/4

動態分配紋理分辨率

Depth Bias

深度偏移量

0.01-0.1

防止自陰影偽影

Normal Bias

法線偏移量

0.5-2.0

改善尖鋭邊緣陰影

該實現結合了URP的ShadowCaster管線與自定義Shader,通過級聯陰影和PCF濾波達到平衡性能與質量的效果

參數説明與用例

參數

説明

典型值

Strength

陰影濃度

0.5-1.0

Bias

防止自陰影

0.05-0.2

Normal Bias

法線偏移

0.3-0.7

Resolution

精度等級

High/Very High

實際應用場景:

  • 動態物體陰影:配合CSM實現高質量移動物體陰影
  • 性能敏感場景:中低端設備可降低Resolution至Medium
  • 特效增強:結合Decal系統實現彈孔等動態貼花效果

完整配置流程

  • 創建Renderer Feature並附加到URP Asset
  • 編寫Shader處理深度比較邏輯
  • 通過Frame Debugger驗證陰影生成階段
  • 調整Bias參數消除陰影瑕疵

關鍵Shader需包含以下處理:

  • 深度重建世界座標
  • 光源空間座標轉換
  • 陰影強度插值計算