【URP】Unity[后處理]景深DepthOfField
【從UnityURP開始探索游戲渲染】專欄-直達
Unity URP中的景深(Depth of Field)是一種模擬真實相機光學特性的后處理效果,通過模糊近處或遠處的物體來突出焦點區域,增強畫面層次感和真實感。其發展經歷了從Built-in管線的基礎實現到URP/HDRP的物理化演進過程,早期采用高斯模糊近似,現代則引入散景(Bokeh)等更接近真實光學特性的算法。
核心作用
- ?視覺引導?:突出主體對象,弱化背景干擾
- ?增強真實感?:模擬攝影鏡頭物理特性
- ?藝術表現?:通過散景光斑創造氛圍
實現原理
基于深度緩沖區計算彌散圈(Circle of Confusion),通過多Pass模糊處理非焦點區域。URP提供兩種模式:
- ?高斯模式?:性能優先,僅支持遠場模糊
- ?散景模式?:質量優先,模擬光圈葉片光學特性
Unity URP中的景深(Depth of Field)效果基于光學透鏡的物理特性模擬,其核心原理是通過計算混淆圈(Circle of Confusion, CoC)來實現虛實分層。
光學基礎原理
-
?透鏡成像特性?:真實相機中,只有特定距離(焦平面)的物體能清晰成像,其他距離的物體會在傳感器上形成彌散圓斑(CoC),其直徑與光圈大小成正比。URP通過高斯模糊或散景模式模擬這一現象,前者計算效率高但物理準確性較低,后者更接近真實光學效果。
-
?CoC計算?:每個像素的模糊程度取決于其深度值與焦點距離的差值。計算公式為:
CoC = |(d_l * f * (z - z_f)) / (z * (f + z_f))|
其中
d_l為光圈直徑,f為焦距,z為物體距離,z_f為對焦平面距離5。URP在Shader中通過深度紋理(_CameraDepthTexture)獲取每個像素的z值。
URP實現流程
-
?預處理階段?:生成包含CoC數據的紋理。通過比較像素深度與焦點距離,標記需要模糊的區域(近景或遠景)。示例參數包括:
csharp [Range(0.1f, 100f)] public float focusDistance = 10f;// 焦點距離 [Range(0.1f, 10f)] public float focusRange = 3f;// 清晰范圍 [Range(1f, 10f)] public float bokehRadius = 4f;// 散景強度 -
?模糊處理?:根據CoC數據對非焦點區域進行分層模糊。URP提供兩種方式:
- ?高斯模糊?:使用降采樣+上采樣的多Pass模糊,適合性能敏感場景
- ?散景模糊?:模擬光學透鏡的虛化效果,在高亮區域生成光斑(Bokeh),需額外計算亮度閾值
-
?合成階段?:將模糊后的圖像與原圖按CoC權重混合。清晰區域的權重為,模糊區域根據CoC半徑插值。
示例代碼邏輯
以下為簡化版CoC計算Shader代碼片段:
hlsl
float4 Frag(Attributes input) : SV_Target {
float depth = SampleDepthTexture(_CameraDepthTexture, input.uv);
float linearDepth = Linear01Depth(depth);
float coc = saturate(abs(linearDepth - _FocusDistance) / _FocusRange);
return float4(coc, coc, coc, 1);
}
該代碼生成CoC圖,白色表示完全模糊,黑色表示完全清晰。完整實現還需結合多尺度模糊和色調映射處理。
性能優化
- ?降采樣?:在Half/Quarter分辨率下計算模糊,減少像素處理量
- ?動態調整?:根據平臺性能切換高斯/散景模式,移動端建議使用高斯模糊
- ?焦點追蹤?:通過射線檢測動態更新
focusDistance,實現自動對焦效果
完整實現流程
-
URP_DepthOfFieldSetup.cs
using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class URP_DepthOfFieldSetup : MonoBehaviour { [SerializeField] private VolumeProfile volumeProfile; void Start() { var depthOfField = volumeProfile.Add<DepthOfField>(); depthOfField.mode.value = DepthOfFieldMode.Bokeh; depthOfField.focusDistance.value = 5f; depthOfField.aperture.value = 5.6f; depthOfField.focalLength.value = 50f; } } -
DoF_Shader.shader
Shader "Custom/DoF" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Pass { // 深度采樣與模糊處理 } } }
參數詳解
| 參數 | 作用 | 典型值 |
|---|---|---|
| Focus Distance | 焦點平面距離 | 3-10m |
| Aperture | 光圈大小(f值) | 1.4-16 |
| Focal Length | 鏡頭焦距(mm) | 35-200mm |
| Blade Count | 光圈葉片數 | 5-9片 |
實際應用案例
- ?角色特寫?:聚焦角色面部,模糊環境
- ?場景過渡?:動態調整焦點實現鏡頭語言
- ?UI突出?:模糊游戲界面背景
性能優化建議
- 移動端使用高斯模式
- 控制Blur Iterations≤3
- 采用DownSample降低分辨率
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,??)

Unity URP中的景深(Depth of Field)是一種模擬真實相機光學特性的后處理效果,通過模糊近處或遠處的物體來突出焦點區域,增強畫面層次感和真實感。其發展經歷了從Built-in管線的基
浙公網安備 33010602011771號