URP - RendererFeature :Depth of Field(gather)
景深效果
独立作品
- ENGINE
- Unity · URP
- TECH
- RenderFeature · rendering · Shader · 后处理 · Pipeline · URP · unity
- ROLE
- 工具
- YEAR
- 2026
案例目录23 小节
效果理解
对于⼀个给定设置的相机镜头,它有⼀个物体聚焦的范围,即它的景深(depth of field)。任何超出这个范围的物体都是模糊的,距离越远越模糊
DoF本质是:离焦平面越远的像素,模糊半径(CoC)越大。CoC也可以叫容许弥散圆

参考视频
焦距,光圈
https://www.bilibili.com/video/BV19W411M7Jx?vd_source=6519de45bf96ecc7dc76d9b36fe3cdcd
焦点、焦距、主光轴
https://www.bilibili.com/video/BV1Gu4y127mU?vd_source=6519de45bf96ecc7dc76d9b36fe3cdcd
景深光圈等介绍,同时解释了弥散圆概念
https://www.bilibili.com/video/BV1t24y1k7Ye?vd_source=6519de45bf96ecc7dc76d9b36fe3cdcd
相机的物理属性
焦距和焦点
对于现实中的相机,控制视野范是焦距,这个焦距由透镜的本身物理属性决定,人眼对应的焦距是50mm

焦距短 → 视角宽,能看到很大范围,物体显得小而远
焦距长 → 视角窄,只能看到一小块,物体显得大而近
景深和焦深

同光圈下,焦距越长,同样距离的物体,背景模糊越强烈。长焦镜头收集光线的方式导致CoC半径更大。大致是长焦拍人像,短焦拍大场景。
相关方案
RTR4中提到的以及AI总结的几种方案如下:
| 引擎 | 方案 |
|---|---|
| URP Gaussian DoF | 可分离高斯,移动端 |
| URP Bokeh DoF | Scatter-as-Gather,高质量 |
| HDRP DoF | Gather+Scatter混合,物理相机参数 |
| UE(旧) | Hexagonal Bokeh |
| UE(新) | Scatter-as-Gather,Circle DoF |
Accumulation Buffer(累积缓冲区)
RTR4中提到可以使用累积缓冲区的方法模拟景深,原理是在相机镜头处取一个圆形区域模拟光圈,对圆盘上的多个位置分别渲染,每次渲染时视线方向都朝向focal plane上的同一个焦点。焦平面上的物体每次位置一致,叠加后清晰;焦平面外的物体每次位置略有偏移,叠加后自然模糊。这种方法物理上更准确,但需要渲染N张图再平均,性能开销极大,不适合实时渲染。

CoC后处理(gather)
假设像素周围的局部邻域都具有相同的深度,可以进行聚集(gather)操作。对同一深度区间的像素进行模糊,高斯模糊是圆形的,那么这样可以去模拟弥散圆,缺陷是在背景高光很明显的情况下会向前方物体的边缘溢色,同时不能满足前景向背景溢色

Scatter(散射)
CoC后处理默认是Gather思路,每个像素去采集周围的贡献。但前景虚化有个问题:前景模糊的像素应该”溢出”覆盖到后面的清晰区域,Gather做不到这点。 Scatter反过来,每个大CoC的像素主动把自己”扩散”到周围像素上,用Compute Shader把像素当作小精灵(sprite)渲染出去。质量好但实现复杂。 实践中常见的是Scatter-as-Gather:用Tile预处理找出每个区域最大CoC,再用Gather模拟Scatter的效果,避免真正的Scatter开销。

分布式光线追踪
就是Accumulation Buffer的光追版本,在光圈圆盘上随机采样光线方向,天然支持正确的DoF。离线渲染(电影)的标准方案,实时不适用。
DoF(gather)实现
直觉参数设计
最简单的参数就是定一个平面作为焦平面,然后设置一个阈值,在这个差值范围内就是清晰的,其余区域是模糊的,模糊程度再用另一参数控制

对应参数是这样的

物理参数的转化
因为现实中物理相机的景深与光圈有关,而且景深并非是关于焦平面对称的,如果更符合现实的话就需要转换一下参数

透镜的成像公式,焦距和物距像距的关系
- = 焦距
- = 物距(物体到透镜的距离)
- = 像距(透镜到感光元件的距离)
那么这样可以得到像距的表达式,像距就是对焦距离,也就是物体成像最清晰的位置,也就是感光元件的位置
根据感光元件位置,再来对比真正的物体成像位置,可以得到物体成像位置和对焦位置两者的差值,如果两个差值较小,那么就认为是清晰的,反之就需要模糊

光圈直径 =, 从几何关系(相似三角形)推出CoC:
最终展开化简后就得到:
CoC计算
第一个Pass,计算CoC后直接存入RT的A通道中后面备用,场景颜色也存入RGB通道

高斯模糊计算
第二个Pass,就是计算模糊了,圆形渐变自然是起手高斯模糊,强度则由CoC控制,这里是水平模糊

合成
第三个Pass,还是同样读取CoC然后进行垂直高斯模糊

然后合成,计算CoC的时候保留正负值,这样就可以针对前景背景设置不同强度的模糊

最简的景深这三个Pass就足够了,高斯的效果如下,效果其实还是可以的

关于模糊的优化
因为模糊不太需要高频信息,为了减少像素的处理量,可以考虑先对RT进行降分辨率在进行模糊,虽然质量会有所下降,但是这样可以少处理很多像素

同样参数下效果如下,因为降分辨率,所以GaussianHalf参数需要降低才能匹配差不多的效果

关于散景Bokeh
在物理相机中,因为光圈数量不同,模糊出现形状也不一样,这种模糊效果被称为Bokeh,如果要实现的话,其实本质上就是用不同的模糊算法
BokehCircle圆形
关于算法可以去看这个网站,直接让ai帮忙写也可以 https://mini.gmshaders.com/p/phi 大致的分布就是这样

代码如下*

效果如下,方便观察我把强度设定的很高,高光成圆形,适合较亮的灯光和高光效果

BokehHexagon 六边形
因为六边形计算其实很费性能,所以有个简化版
高质量
对于第二中就是六边形的散布,最简单的就是直接在原有基础上剔除掉就行

效果如下

简化版
简化版使用3Pass,向三个方向拉伸,然后组合得到六边形,下面是代码,注释内容是借用了高斯的权重,这样会非常平滑,六边形特征有些微弱,我觉得效果不好换成了平均权重 垂直方向

30度方向拉伸

-30度方向拉伸

效果如下,效果稍差

当前效果和缺陷
因为gather算法的问题,在亮度差异比较大的情况下,背景模糊溢色会污染前面物体的边缘

同时前景模糊并不能向后晕染,尽管对前景的模糊程度进行了强化,也只是模拟一点效果


不过这个缺陷其实不是很严重,从效果说来说已经可以使用了,如果需要彻底解决就需要使用Scatter(散射)的方案去解决了,这个后续有时间我再去学习研究研究 DOF加上之前Bloom,FXAA,我觉得还不错
