在这个简短的视频中,我将向你展示如何在 Unity 中创建一个动态 Defocus 效果,使画面只对准摄像机视野中央的对象进行对焦,同时对其他对象进行模糊处理。
本教程的视频版本目前尚未提供该语言版本。您可以在下方观看带字幕的英文版视频;视频下方提供了翻译成中文的文字稿。
视频文字稿
大家好。在这个简短的视频中,我将向你展示如何在 Unity 中创建一个动态 Defocus 效果,使画面只对准摄像机视野中央的对象进行对焦,同时对其他对象进行模糊处理。
现在我通过夸张的模糊效果来展示最终结果。这个效果是可以自定义的,稍后我会向你展示如何进行设置。

本视频和脚本基于 Unity 2022 以及 Universal Rendering Pipeline 创建。
要正确使用该脚本,你需要在 Main Camera 上添加一个 Volume 组件,这样才能访问 Depth of Field 子组件。

你需要将 Defocus 组件的模式更改为 Bokeh。该模式允许你指定焦点距离以及其他效果参数,从而使最终效果更加真实。

接下来我们需要启用 Focus Distance 和 Aperture 参数。

对于 Focus Distance,可以保留默认值,因为我们将在游戏运行时通过 C# 脚本动态修改这个数值。
关于 Aperture 参数,需要注意的是,该值越小,选择性对焦效果越明显,因为景深会变得更浅。
在最初示例中,为了刻意夸张效果,我将该值设置为 2.4。当然,在你的项目中需要通过测试来设置合适的数值。
在展示实现脚本的代码之前,我先简要说明它的工作原理。
脚本会从摄像机向虚拟场景画面中心发射一条不可见的射线,称为 Raycast。
当这条射线击中带有 Collider 组件的对象时,脚本会计算该对象与摄像机之间的距离,并将这个数值写入 Depth of Field 子组件中的 Focus Distance 字段。
整个操作非常简单,但需要注意的是,要被检测到的对象必须包含 Collider 组件。如果你不希望这些对象阻挡角色移动,也可以将 Collider 设置为 Trigger 模式。

现在我们来看一下这个非常简单的 C# 脚本,我将其命名为 Dynamic Defocus。
要使脚本正常运行,你需要导入 Rendering 和 Rendering Universal 模块。

我定义的私有变量仅用于访问 Volume 组件及其 Depth of Field 子组件,以便我们可以修改相关参数。

Volume 和 Depth of Field 变量会在脚本的 Start 函数中进行初始化。

在 Update 函数中,也就是每一帧都会自动执行的函数中,会投射 Raycast 射线。

被射线击中的对象会写入 hit 变量。但该对象可能不存在,例如当用户将视线对准背景,或者对准场景中没有 Collider 组件的区域时。
因此,在将 hit 变量中的 Distance 数值赋给 Depth of Field 组件的 Focus Distance 参数之前,必须先检查 hit 的 Collider 是否为 null。
如果需要获取被射线拦截的对象名称,可以通过访问 hit 变量的 Collider 组件,然后访问该组件的 Game Object,最后读取其 name 属性。
保存脚本后,请在你的项目中进行测试,并调整 Aperture 参数的数值,直到获得理想的效果。
希望这个简短的视频对你有所帮助。我们下次再见。