1. 项目概述:为什么我们需要跨管线掌握景深?
如果你在Unity里做过一段时间的美术或者技术美术,大概率会对“景深”这个效果又爱又恨。爱的是,它几乎是提升画面电影感、引导玩家视觉焦点最直接有效的手段之一;恨的是,在不同的渲染管线里,它的实现方式、参数调节和性能开销简直是天差地别。我见过太多项目,从Built-in管线迁移到URP或HDRP时,之前调得漂漂亮亮的景深效果直接“罢工”,或者变得性能堪忧,美术同学不得不从头再来。
所以,这个“跨管线实现指南”的核心价值就在这里:它不是教你如何在某一个管线里把景深开关打开,而是帮你建立起一套可迁移的知识体系。让你明白在Built-in、URP、HDRP这三种主流管线下,景深效果背后的原理差异、实现路径和调优心法。无论你是接手一个老项目,还是为一个新项目选择技术方案,或者单纯想深入理解Unity的后处理栈,这篇文章都能让你避开我踩过的那些坑,直达效果与性能的平衡点。
简单来说,我们将从最经典但已“退役”的Built-in管线讲起,理解其实现原理作为基础;然后深入到目前应用最广泛的URP(通用渲染管线),掌握其轻量高效的景深方案;最后攻克代表高品质的HDRP(高清渲染管线),解锁其基于物理的、电影级的高质量景深。你会发现,虽然表面都是“模糊”,但内核逻辑完全不同。
2. 核心原理与管线差异:从“后处理滤镜”到“物理模拟”
在深入实操之前,我们必须先理清一个根本问题:为什么不同管线的景深实现起来不一样?这源于它们截然不同的设计哲学和渲染架构。
2.1 Built-in管线:传统的后处理堆栈时代
在Built-in管线(也称前向渲染管线)中,景深是一个标准的后处理效果。它的工作流程非常直观:
- 渲染场景:摄像机完成场景的颜色和深度缓冲渲染。
- 应用后处理:通过
OnRenderImage方法或传统的Post Processing Stack v2插件,对上一帧的渲染结果(一张纹理)进行处理。 - 基于深度的模糊:景深效果的核心是深度纹理。系统根据当前像素的深度值(即距离摄像机的远近),与一个设定的“对焦距离”进行比较。距离对焦平面越远的像素,其模糊半径(Kernel Size)就越大。然后,通过一个高斯模糊或散景模糊算法,对原图进行采样和混合,生成最终的模糊效果。
Built-in景深的特点:
- 实现简单:概念清晰,易于理解。很多自定义Shader的教程都以此为基础。
- 控制直观:参数如对焦距离、模糊半径、光圈形状(散景)通常直接可调。
- 性能开销相对固定:模糊采样次数和范围决定了开销,但缺乏精细的LOD控制。
- 已停止更新:Unity官方已不再为Built-in管线添加新功能,这意味着一些更先进的算法和优化(如TAA结合的抗锯齿)可能无法使用。
注意:虽然Built-in管线逐渐淡出,但理解它的原理至关重要。它揭示了景深最本质的“基于深度图的后处理模糊”逻辑,这是所有高级实现的基础。
2.2 URP管线:模块化与效率优先
URP的设计目标是跨平台高性能。它的景深实现被整合进了URP内置的渲染器特性(Renderer Features)和卷(Volume)系统中。你不再需要单独的后处理堆栈资产,而是在URP渲染器资产中直接启用“Depth Of Field”这个后处理效果。
URP景深的进化:
- 集成化:效果直接作为URP包的一部分,无需额外导入资源包(但需在Package Manager中安装
Universal RP和Post Processing)。 - 基于Volume框架:效果通过Volume组件在场景中局部或全局应用,可以混合、叠加,非常适合制作不同区域的视觉效果(如进入房间后景深变强)。
- 算法优化:URP通常使用一种称为“散景模糊(Bokeh Blur)”的高效算法。它不像传统高斯模糊那样均匀模糊所有区域,而是更智能地模拟镜头光圈形状,在焦外高光点产生漂亮的光斑(散景),在非高光区域则使用性能更优的模糊方式。
- 分级质量:URP的景深设置通常提供“性能(Performance)”、“质量(Quality)”、“最高质量(High Quality)”等选项,让你在移动端和PC端之间灵活权衡。
URP与Built-in的核心区别:URP将景深从“一个独立的后处理滤镜”变成了“渲染管线的一个可配置特性”,使其更深度地集成到渲染流程中,从而有机会做更多底层优化(如与渲染目标、抗锯齿的配合)。
2.3 HDRP管线:物理正确与电影级质量
HDRP是为追求极致视觉效果的PC/主机平台设计的。它的景深不仅仅是“一个效果”,而是对真实世界摄像机光学特性的物理模拟。
HDRP景深的质变:
- 物理摄像机驱动:这是最大的不同。在HDRP中,你可以直接将景深的
Focus Mode设置为“Use Physical Camera”。此时,对焦距离、光圈大小(Aperture)、焦距等参数,完全由摄像机组件上的物理属性驱动。这意味着,如果你有摄影知识,可以直接套用真实世界的参数(如f/2.8的光圈),效果会极其逼真。 - 高质量算法:HDRP的景深算法更为复杂和精确。它支持前后景分开控制(Near Blur, Far Blur),可以独立设置前景和背景模糊的开始/结束距离、采样数量和最大模糊半径。这在模拟浅景深、突出特定物体时非常有用。
- 散景形状自定义:通过
Blade Count(光圈叶片数)和Curvature(叶片曲率)参数,你可以精确控制焦外光斑的形状,从完美的圆形到多边形的星芒,创造出独特的视觉风格。 - 分辨率与过滤质量:HDRP允许你选择景深效果的计算分辨率(如全分辨率、半分辨率、四分之一分辨率),以及是否启用高质量的三次过滤(High Quality Filtering),为性能敏感的场景提供了精细的调控手段。
HDRP的核心思想:它不再满足于“看起来像”模糊,而是要“计算出来”基于物理光学模型的模糊。这带来了无与伦比的真实感和艺术控制力,但同时也对性能提出了更高要求,并且要求使用者对摄影基础有更深的理解。
3. Built-in管线景深实现:经典方案的回顾与实操
尽管Built-in管线已非新项目首选,但大量存量项目、学习资源和自定义Shader开发仍基于此。掌握它,是理解景深原理的必修课。
3.1 使用传统Post Processing Stack v2
这是Unity官方早期为Built-in管线提供的标准后处理解决方案。虽然已归档,但依然稳定可用。
实操步骤:
- 导入资源包:通过Package Manager,从Unity Registry中搜索并安装
Post Processing(版本通常为2.x或3.x,这里指v2风格)。 - 创建后处理配置文件:在Project窗口右键 -> Create -> Post-processing Profile。这会创建一个
.asset文件。 - 配置摄像机:
- 选中主摄像机。
- 添加
Post-process Volume组件。 - 将刚创建的Profile文件拖入组件的
Profile槽位。 - 勾选
Is Global,使其影响整个场景。
- 启用景深:
- 在Inspector中,点击Post-process Volume组件下的
Add effect...-> Unity -> Depth of Field。 - 现在,你可以调整景深的各项参数了。
- 在Inspector中,点击Post-process Volume组件下的
关键参数解析:
- Focus Distance:对焦平面的距离。你可以手动拖动滑块,也可以启用
Use Camera FOV来自动计算。 - Aperture:光圈值(f-stop)。数值越小(如f/1.4),光圈越大,景深越浅(模糊范围越大)。这是模拟摄影的关键参数。
- Focal Length:焦距。较长的焦距(如85mm)会压缩空间感,产生更明显的背景模糊。
- Kernel Size:内核大小。决定模糊采样范围,直接影响模糊强度和性能。通常有Small、Medium、Large等选项。
避坑心得:
- 性能注意:
Kernel Size设置为Large或Very Large时,在移动端或低配PC上可能造成明显的帧率下降。在移动项目上务必谨慎使用,或考虑完全关闭。 - 与抗锯齿的冲突:如果同时启用了MSAA等抗锯齿,可能会与后处理效果(尤其是基于深度的)产生冲突,导致边缘闪烁或模糊异常。通常建议在后处理场景中,使用基于摄像机的抗锯齿(如FXAA、SMAA)或TAA。
- 深度纹理必须开启:景深依赖深度缓冲。确保你的摄像机或Graphics Settings中启用了
Depth Texture。如果景深不生效,首先检查这里。
3.2 手动编写简易景深Shader(原理理解)
为了彻底搞懂原理,我们可以尝试写一个极度简化的景深Shader。这能让你明白,所谓的“模糊”是如何与深度信息结合的。
Shader "Custom/SimpleDepthOfField" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _DepthTex ("Depth Texture", 2D) = "white" {} _FocusDistance ("Focus Distance", Float) = 10.0 _FocusRange ("Focus Range", Float) = 5.0 _BlurSize ("Blur Size", Float) = 1.0 } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; sampler2D _DepthTex; float _FocusDistance; float _FocusRange; float _BlurSize; float4 _MainTex_TexelSize; // 每个纹素的大小 v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { // 1. 采样当前像素的颜色和深度 fixed4 originalColor = tex2D(_MainTex, i.uv); float depth = tex2D(_DepthTex, i.uv).r; // 将深度值转换为线性视空间深度(简化版,实际更复杂) float linearDepth = LinearEyeDepth(depth); // 2. 计算模糊系数:基于深度与对焦距离的差值 float depthDiff = abs(linearDepth - _FocusDistance); float blurFactor = saturate(depthDiff / _FocusRange); // 0到1之间 // 模糊系数越大,采样范围越大 float currentBlurSize = blurFactor * _BlurSize; // 3. 简单的均值模糊(仅作演示,实际用高斯模糊) fixed4 blurredColor = originalColor; int sampleCount = 0; // 在周围像素采样 for (int x = -2; x <= 2; x++) { for (int y = -2; y <= 2; y++) { float2 offset = float2(x, y) * _MainTex_TexelSize.xy * currentBlurSize; blurredColor += tex2D(_MainTex, i.uv + offset); sampleCount++; } } blurredColor /= sampleCount; // 4. 根据模糊系数混合原始颜色和模糊颜色 return lerp(originalColor, blurredColor, blurFactor); } ENDCG } } FallBack "Diffuse" }这段代码说明了什么?
- 它需要一张深度图(
_DepthTex),通常由摄像机渲染后提供。 - 它计算每个像素距离对焦平面有多远(
depthDiff)。 - 根据这个距离,决定一个模糊强度(
blurFactor)和采样范围(currentBlurSize)。 - 最后,根据模糊强度,将原始清晰的像素颜色和周围采样模糊后的颜色进行混合。
这就是景深最核心的逻辑。当然,生产级的实现会复杂得多,包括高性能的模糊算法(如双重模糊)、散景模拟、抗锯齿处理等,但万变不离其宗。
4. URP管线景深实战:轻量高效的配置之道
URP是目前Unity项目的绝对主流。它的景深配置流程标准化程度很高,但要想调出好效果,仍需理解其参数内涵。
4.1 基础配置与启用
- 确保URP环境:通过Package Manager安装
Universal RP包,并创建一个URP Asset(右键 -> Create -> Rendering -> URP Asset (with Universal Renderer)`)。将其赋给Project Settings -> Graphics中的Scriptable Render Pipeline Settings。 - 启用后处理:在URP Asset关联的Renderer(如Universal Renderer Data)中,确保
Post Processing选项是勾选的。 - 创建Volume并添加效果:
- 在场景中创建一个空物体,添加
Volume组件。 - 点击
New创建一个新的Volume Profile,或使用一个已有的。 - 在Volume组件上,点击
Add Override->Post-processing->Depth of Field。
- 在场景中创建一个空物体,添加
完成以上步骤,景深效果就已经应用到该Volume影响的摄像机了。如果Volume是Is Global,则影响所有摄像机。
4.2 核心参数深度解析
URP的Depth of Field组件提供了几个关键模式,对应不同的控制逻辑:
- Mode: Gaussian:使用经典的高斯模糊。性能较好,但效果相对平淡,缺乏光学特征(如散景光斑)。参数简单,只有
Start(模糊开始距离)、End(模糊结束距离)、Max Radius(最大模糊半径)。适合移动端或风格化渲染。 - Mode: Bokeh:推荐使用。模拟镜头光圈形状,能产生高质量的焦外散景。这是URP景深的精髓。
Focus Distance: 对焦距离。Aperture: 光圈值。这是最重要的艺术控制参数。f值越小(如2.8),光圈越大,景深越浅,模糊越强。Focal Length: 焦距。与Built-in中类似,控制视野和空间压缩感。Blade Count: 光圈叶片数。控制散景光斑的形状(圆形、六边形、八边形等)。叶片数越多,光斑越接近圆形。Blade Curvature: 叶片曲率。值越大,叶片越弯曲,散景光斑的边缘越圆滑。Blade Rotation: 叶片旋转角度。
实操技巧:如何快速调出电影感?
- 先定焦点:将
Focus Distance对准你想要玩家关注的核心物体(比如角色面部或一个关键道具)。 - 开大光圈:将
Aperture调到较低的值(如f/2.0或f/1.8),立刻获得强烈的背景虚化。 - 调整焦距:根据构图需要调整
Focal Length。长焦(如85mm)能更好地隔离主体,但会压缩空间;广角(如24mm)则能保留更多环境信息。 - 微调散景:通过
Blade Count和Curvature为高光点(如灯光、反光)添加风格化的光斑形状,这是提升画面“高级感”的秘诀。
4.3 URP景深性能优化指南
URP景深在移动端使用时必须精打细算。以下是我的实战优化清单:
- 优先使用Bokeh (Fast) 模式:URP通常提供一个
Bokeh (Fast)选项,它使用更优化的采样算法,在视觉质量损失不大的情况下,性能显著优于标准Bokeh模式。在移动平台上,无脑选Fast模式。 - 降低分辨率:在URP Asset的Quality设置中,可以降低渲染分辨率(如设置为0.75倍)。景深作为后处理效果,其计算基于渲染分辨率,降低分辨率能直接减轻GPU负担。配合FSR或DLSS等超分辨率技术,可以在性能与画质间取得更好平衡。
- 控制模糊半径(Max Radius):这是性能杀手。
Max Radius决定了模糊采样的最大范围。在移动端,尽量将其保持在较低水平(如3-5)。过大的半径(>10)会导致采样数暴增。 - 善用Volume混合:不要全局使用高强度景深。利用Volume的
Blend Distance和Weight,只在特写镜头、室内场景等需要突出氛围的区域启用高强度的景深,在开阔的室外场景则减弱或关闭它。 - 注意透明物体:景深基于不透明物体的深度缓冲。半透明物体(如粒子、UI)的渲染顺序在后处理之后,因此不会被正确模糊。如果需要模糊UI,需要额外的渲染层和自定义处理,这非常消耗性能,移动端应尽量避免。
5. HDRP管线景深实战:追求物理真实的艺术控制
HDRP的景深是专业级的工具,参数繁多,但逻辑清晰。我们的目标是学会用摄影师的思维去使用它。
5.1 物理摄像机工作流详解
这是HDRP景深最强大也最推荐的工作流。它要求你的摄像机启用Physical Camera属性。
配置流程:
- 启用Physical Camera:在HDRP摄像机组件的
General部分,勾选Physical Camera。 - 设置镜头属性:
Focal Length: 设置镜头的焦距,如50mm标准镜头。Sensor Size: 设置传感器尺寸(如全画幅的36x24mm)。这会影响视野(FOV)。Aperture: 设置光圈值(f-stop)。这是控制景深虚化程度的核心。
- 在Volume中配置景深:
- 添加
Depth of Field覆盖。 - 将
Focus Mode设置为Use Physical Camera。 - 此时,
Focus Distance参数将不再直接显示,因为它由摄像机的对焦系统驱动。
- 添加
如何对焦?在Use Physical Camera模式下,你有两种对焦方式:
- 自动对焦:使用摄像机的
Focus Mode设置为Continuous或Single,并指定一个Focus Target(一个Transform)。摄像机会自动计算到该目标的距离作为对焦距离。这在跟踪移动角色时非常有用。 - 手动对焦:将摄像机的
Focus Mode设置为Manual,然后直接调整Focus Distance参数。你也可以在Scene视图中,看到摄像机上出现的对焦平面Gizmo,直接拖动它来直观地对焦。
为什么推荐物理模式?因为它保证了视觉一致性。当你调整焦距(Focal Length)或光圈(Aperture)时,景深的变化完全符合物理规律。例如,将焦距从35mm切换到200mm,即使物体在画面中的大小不变,背景的虚化程度也会显著增加。这种 predictability(可预测性)对于电影级镜头语言的控制至关重要。
5.2 高级参数:Near Blur与Far Blur的独立控制
HDRP允许你分别控制前景和背景的模糊,这提供了无与伦比的艺术灵活性。
- Near Blur:控制对焦平面前方物体的模糊。
Start: 距离摄像机多近开始出现模糊。End: 距离摄像机多远时,前景模糊达到最大强度。Sample Count: 采样数,影响前景模糊的质量和性能。Max Radius: 前景模糊的最大半径。
- Far Blur:控制对焦平面后方物体的模糊。参数同上。
应用场景: 想象一个镜头:角色站在窗前(对焦点在角色),窗外是模糊的街景(Far Blur),窗玻璃上可能还有雨滴,这些雨滴如果离镜头很近,也可以被处理成前景模糊(Near Blur)。通过独立控制,你可以让前景的雨滴模糊得柔和一些,而让背景的街景模糊得更强烈,从而创造出丰富的空间层次感。
5.3 HDRP景深质量与性能的权衡表
HDRP景深提供了多个质量杠杆。下表清晰地展示了如何根据项目需求进行配置:
| 参数/设置 | 高质量(电影/过场动画) | 平衡质量(PC游戏运行时) | 性能优先(主机/高端移动) | 说明 |
|---|---|---|---|---|
| Focus Mode | Use Physical Camera | Use Physical Camera 或 Manual | Manual | Physical模式最真实,但Manual在需要绝对控制时更直接。 |
| Resolution | Full Resolution | Half Resolution | Quarter Resolution | 对性能影响最大。降到1/4分辨率,性能提升显著,质量损失在动态游戏中常可接受。 |
| High Quality Filtering | 启用 | 视情况启用 | 关闭 | 启用后使用三次滤波,模糊更平滑,但消耗更大。 |
| Sample Count (Near/Far) | 8-10 | 5-7 | 3-5 | 采样数直接影响模糊质量。前景采样可比背景略高,因前景更易被注意。 |
| Max Radius (Near/Far) | 根据艺术需求 | 通常< 10 | 通常< 5 | 限制最大模糊半径是控制性能的关键。避免无限制的极端模糊。 |
| Aperture Shape | 自定义 (Blade Count=8+) | 六边形 (Blade Count=6) | 五边形或默认 | 更多叶片数需要更多计算,但散景更圆润美观。 |
一个重要的性能技巧:使用Volume优先级和混合。 在HDRP中,你可以设置多个Volume,并赋予不同的Priority。可以创建一个低优先级的全局Volume,使用低质量的景深设置(如Quarter Res)。然后,在需要特写的区域(如对话镜头)放置一个高优先级的局部Volume,覆盖高质量设置(如Half Res, High Quality Filtering)。这样,大部分时间运行的是高性能配置,只在关键时刻才付出高质量的成本。
6. 跨管线迁移策略与常见问题排雷
当你需要将一个项目的景深效果从一条管线迁移到另一条时,直接复制参数是行不通的。你需要的是策略和问题排查能力。
6.1 从Built-in/URP迁移到HDRP
这是最常见的升级路径。核心思想是:从“数值控制”思维转向“物理模拟”思维。
参数映射与转换:
- 对焦距离:直接对应。在HDRP的
Manual模式下设置相同的Focus Distance。 - 模糊强度/光圈:这是关键。在Built-in/URP中,你可能用一个
Blur Size或Aperture值来控制强度。在HDRP中,你需要通过光圈值(Aperture)和焦距(Focal Length)共同作用来达到相似的虚化程度。一个粗略的起点是:在HDRP中,使用50mm焦距,然后调整Aperture直到背景模糊程度看起来与之前“感觉”一致。可能需要配合调整Max Radius。 - 散景形状:如果原项目使用了自定义散景,需要在HDRP中通过
Blade Count和Curvature来近似模拟。
- 对焦距离:直接对应。在HDRP的
工作流适应:
- 拥抱Volume系统:放弃旧的Post-process Volume组件,全面转向HDRP的Volume框架。
- 学习物理摄像机:花时间理解焦距、光圈、传感器尺寸之间的关系。网上有很多摄影的“景深计算器”,可以帮助你从物理角度预判效果。
6.2 从HDRP降级到URP
这种情况较少,但可能在针对低端平台时发生。核心是:保留视觉感觉,放弃物理精确性。
- 效果近似:
- HDRP中精细的前后景独立控制,在URP中无法直接对应。你需要通过一个
Focus Distance和Focus Range(或Start/End)来模拟一个整体的模糊过渡。 - HDRP的高质量散景,在URP的Bokeh模式下可以较好地还原,但可能需要降低
Sample Count来保证性能。
- HDRP中精细的前后景独立控制,在URP中无法直接对应。你需要通过一个
- 性能重估:HDRP的高质量设置(如Full Resolution + High Quality Filtering)在URP中可能根本不存在对应选项,或者性能开销依然不可接受。必须根据URP的目标平台重新制定性能预算。
6.3 高频问题与解决方案实录
以下是我在项目和社区支持中反复遇到的典型问题:
问题1:景深效果完全没有出现。
- 排查步骤:
- 检查Volume是否生效:确保摄像机在Volume的
Collider范围内(如果是局部Volume),或Is Global已勾选。检查Volume的Weight是否大于0。 - 检查后处理是否启用:在URP/HDRP的渲染器资产中,确认Post-processing已开启。
- 检查深度纹理:这是最常见的原因。在URP中,检查摄像机或URP Asset的
Opaque Texture设置(深度信息包含其中)。在HDRP中,确保Frame Settings中Custom Passes或相关选项允许深度生成。 - 检查抗锯齿:某些抗锯齿(如TAA)可能与后处理有冲突。尝试切换为FXAA或关闭抗锯齿进行测试。
- 检查Volume是否生效:确保摄像机在Volume的
问题2:景深导致画面闪烁或边缘有光晕/黑边。
- 原因与解决:
- 深度缓冲精度问题:在远距离场景中,深度值可能精度不足。尝试调整摄像机的远近裁剪平面(Near/Far Clip Plane),让远平面尽可能接近场景最远物体,以优化深度值分布。
- 半透明物体问题:半透明物体不写入深度缓冲,导致其边缘的景深计算错误。这是一个固有限制。对于重要的半透明物体(如角色头发上的高光),可能需要将其渲染到单独的层,并用自定义方式处理。
- 分辨率过低:在HDRP中,如果将
Resolution设为Quarter,且High Quality Filtering关闭,在物体边缘容易产生锯齿状闪烁。可尝试升级到Half分辨率,或轻微增加Max Radius。
问题3:移动设备上开启景深后帧率暴跌。
- 性能优化组合拳:
- 首选URP Bokeh (Fast)模式。
- 大幅降低分辨率:在URP渲染器设置中将渲染缩放降至0.5-0.75。
- 严格控制模糊半径:确保
Max Radius不超过5。 - 使用动态开关:写一个简单的脚本,根据摄像机与主角的距离或游戏状态(如战斗/探索)来动态调整Volume的
Weight,甚至完全禁用景深。 - 考虑替代方案:对于极度性能敏感的场景,可以考虑使用一个简单的径向模糊(Radial Blur)或自定义的屏幕空间遮罩来模拟“注意力集中”的效果,而非全屏物理景深。
问题4:焦平面过渡非常生硬,像一刀切。
- 解决:调整
Focus Range(URP)或Near/Far Blur的Start和End范围(HDRP)。让模糊有一个平滑的过渡区间,而不是在某个距离上突然从清晰变成完全模糊。在HDRP中,拉大End和Start之间的差值;在URP中,增加Focus Range的值。
掌握这些跨管线的实现、调优和排错技巧,意味着你不仅能在Unity中做出漂亮的景深效果,更能让这个效果在任何技术环境下都稳定、高效地运行。这正是一名技术美术或图形程序员的核心价值所在——在艺术表现与技术约束之间,找到那条最优的路径。