Unity 景深Depth Of Field

目录

 

介绍

准备

设置

基于Unity Builtin 管线

基于Unity URP

基于Unity HDRP


 

介绍:

景深效果Depth Of Field是摄影界的老常客了,在游戏中也非常多见,它能够大幅提升游戏画面体验和真实度,使得物体看起来更有细节。

ddb77236d1744e4e8e7e79c1d3f13d7e.png

GTA5中的景深效果

Unity 当然提供了景深支持: Creative Core: Post-processing - Unity Learn

本文我将介绍最简单直接的实现方法,不需要任何复杂的物理学只是,直截了当的就能出效果。

准备

本节将分别介绍Built-in Render,URP,HDRP中的基础景深效果。所有的管线景深都需要用到PostProcessing功能。

首先,三种管线都需要先把简单的前置设置部署好:Built-in Render需要额外安装package,另外两个不用,在package manager中搜索安装 Post Processing,这个插件早晚会用,它提供了全方位的画质颜色和视觉提升。


设置

  • 基于Unity Builtin 管线

更多参考:Post Process Volumes - Unity Learn
基于Unity Builtin 管线, 需要额外安装 PostProcessing package,安装完成后,你需要:

  1. 在Layer设置中增加一个Layer,可以随便命名,但是建议就叫 PostProcessing” ;然后在你想要设置的Camera中增加Post-process Layer组件;接着设置这个组件的Layer为你刚刚新添加的“PostProcessing” ,确组件的Trigger是你想要的相机;
  2. 创建一个空物体,或者你可以继续在Camera中添加,(只要确保和PostProcessing有关的所有对象都有“PostProcessing” Layer!),在这个物体中添加Post-Process Volume
  3. 创建并保存你的Profile,并在Add effect选项中添加Depth Of Field效果,一般来说Apture小一些Focal Length大一些可以得到一个不错的景深效果,之后你就只需要调整焦距Focus Distance就可以了!
  4. d25b81fd5a0d4a8d8293af3fb111b735.png

    b2000b55db004f94bb8f19c63c9c1a1c.png

    d66ff03dda8b4206980ab595b68333f5.png

    55a39e74cad049228fddb855ace33d09.png

    cb971c922872492e906f612c544e6e30.png

     

392a3ae7d3527c6ff4463cf7b4221789.png

如果你需要动态根据距离来调整的话,需要代码接入来更改volume的 Focus Distance,可以动过简单计算相机和焦点物体的距离来更改;另一种方案是通过屏幕中心发射一道射线来判断距离,这里介绍简单的:


using UnityEngine;
using UnityEngine.Rendering.PostProcessing;

public class cameraDist : MonoBehaviour
{
[SerializeField] PostProcessVolume postProcessVolume;
[SerializeField] DepthOfField df;
[SerializeField] Transform player,mainCamera;

void Start()
    {
      
          postProcessVolume.sharedProfile.TryGetSettings<DepthOfField>(out df);

    }
}
void Update()
    {
        df.focusDistance.value = Vector3.Distance(player.position, mainCamera.position);
    }
  • 基于Unity URP

基于Unity URP, PostProcessing 已经默认包含,而且不需要设置Layer。其它设置和Buit-in基本一致,但是确保在相机设置中启用Post Processing功能! 然后直接在相机中添加Volume组件就可以了,其它步骤基本不变,景深设置中可选用Bokeh

 970ee9a6579747cbbcaf8f4516b5ec22.png6d3de5693bec4dcf80ada0ddb3cae913.png

e54cf4b0943148b193b4f00576d2fc9e.png

 

b94cdc49532079d4d0b8c2d29985f7f8.png

动态更改焦距,这里和Built-in类似,只是引用的API不一样,此外,这里使用简单的射线检测,从相机发出一条射线,射到谁就用谁到相机的距离,但这个方法不适用在复杂场景和运动条件下


using UnityEngine;


public class cameraDist : MonoBehaviour
{
    [SerializeField] private UnityEngine.Rendering.Volume postProcessVolume;
    [SerializeField] private UnityEngine.Rendering.Universal.DepthOfField dof;

void Start()
    {
      
              postProcessVolume.profile.TryGet<UnityEngine.Rendering.Universal.DepthOfField>(out dof);

    }
}
void Update()
    {
        RaycastHit hit;
            if (Physics.Raycast(mainCamera.transform.position, mainCamera.transform.forward, out hit, Mathf.Infinity))
            {
                dof.focusDistance.value = hit.distance;
            }
    }
  • 基于Unity HDRP

HDRP就更神奇了,由于更高渲染技术的加持,其图像原理看起来很不一样,这里的相机看起来更像显示世界里的相机了,相机直接按如图设置:

fc24644946ce43708a8619206b638a3e.png

 Volume和景深效果的添加和URP一样,但是它的参数可以被相机的物理信息直接控制了:

800b7c54ffbe43df80f2f5fd91721190.png

5feca6ffc0d6483b864257e686569675.png

hHDRP的动态对焦,脚本这时候就需要直接更改相机属性就行了,但是注意,相机必须设置为物理相机!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;

public class CameraFocus : MonoBehaviour
{
    public Transform target;
    [SerializeField] Camera cam;
    // Update is called once per frame
    private void OnValidate()
    {
        cam = GetComponent<Camera>();
        cam.usePhysicalProperties = true;
        cam.GetComponent<HDAdditionalCameraData>().physicalParameters.focusDistance = Vector3.Distance(transform.position, target.position);
    }
    private void Start()
    {
        cam = GetComponent<Camera>();
        cam.usePhysicalProperties = true;
    }
    void Update()
    {
        FocusByRaycast();
    }
    void FocusByTransform(Transform target)
    {
        // change camera focus distance 
        cam.GetComponent<HDAdditionalCameraData>().physicalParameters.focusDistance = Vector3.Distance(transform.position, target.position);
    }
    void FocusByRaycast()
    {
        //raycast to target hit distance
        RaycastHit hit;
        if (Physics.Raycast(transform.position, transform.forward, out hit))
        {
            // change camera focus distance 
            cam.GetComponent<HDAdditionalCameraData>().physicalParameters.focusDistance = hit.distance;
        }

    }
}

 

 

 

 

 

<think>好的,用户想了解Unity中的URP管线下的Volume中的Depth of Field效果。首先,我得确认自己对URP和Depth of Field的理解是否正确。URP是Unity的通用渲染管线,替代了旧版的Built-in管线,优化了性能和跨平台支持。Volume组件用于后处理效果,Depth of Field景深)是模拟相机对焦效果,让焦点区域清晰,其他区域模糊。 接下来,用户需要详细的信息,可能需要分点说明。首先应该解释Depth of Field的作用和应用场景,比如游戏中的电影感或突出重点。然后,在URP中如何配置,包括Volume组件的添加、参数的设置。需要提到URP和Built-in的区别,比如后处理的实现方式不同,Volume系统是URP的一部分。 可能需要注意URP中Depth of Field的实现方式,比如使用基于物理的景深还是其他方法。参数方面,包括焦点距离、光圈大小、焦距等,需要详细解释每个参数的作用。此外,性能影响也是用户关心的点,可能需要说明不同配置下的性能消耗,比如在移动设备上的优化建议。 用户可能还不太清楚如何实际操作,是否需要步骤指导?比如创建Volume,添加Depth of Field覆盖,调整参数。同时,可能需要提到URP和HDRP的区别,如果用户混淆了这两个管线的话。还要检查是否有最新的Unity版本带来的变化,比如参数名称或功能的调整。 需要确保语言通俗易懂,避免过于专业的术语,或者遇到术语时进行解释。例如,解释“光圈”在景深中的作用,以及“焦外模糊”的效果。此外,可能还要给出使用示例,比如在角色对话时对焦角色,模糊背景,增强沉浸感。 最后,总结部分要强调Depth of Field的重要性以及合理使用的重要性,避免过度使用导致性能问题或视觉疲劳。可能还要提醒用户测试不同设备上的表现,确保兼容性和性能平衡。</think>Unity的URP管线中Depth of Field景深)效果详解: 1. 基础概念 - Depth of Field景深)是模拟真实相机光学特性的后处理效果 - 通过模糊画面中非焦点区域,突出主体对象,增强视觉层次感 - 常用于过场动画、角色特写等电影化场景 2. URP实现特性 - 基于物理的景深模拟(Physically Based DoF) - 支持两种渲染模式: ▸ Gaussian(高斯模糊)- 性能较好但物理精度较低 ▸ Bokeh(焦外成像)- 更真实的镜头光斑效果 - 集成在Volume系统中,支持场景分层配置 3. 核心参数解析 在Volume组件中添加`Depth of Field`覆盖后: - `Focus Distance`(焦点距离): - 控制清晰区域的中心距离(单位:米) - 可通过脚本动态跟踪目标对象 - `Aperture`(光圈值): - f-stop值(例:f/2.8) - 数值越小景深越浅(背景更模糊) - `Focal Length`(焦距): - 模拟镜头焦距(单位:毫米) - 影响模糊区域的过渡形态 - `Blade Count`(光圈叶片数): - 控制Bokeh光斑形状(5-8边形效果最佳) 4. 实战配置步骤 ① 创建Global Volume或Local Volume ② 添加Depth of Field覆盖项 ③ 通过Scene视图焦距辅助线(蓝色线框)实时调整 ④ 结合Cinemachine相机实现动态对焦 ⑤ 测试不同分辨率下的表现(移动端需降低采样) 5. 性能优化建议 - 移动设备推荐使用Gaussian模式 - PC平台可启用Bokeh+高质量采样 - 控制最大模糊半径(Max Radius ≤5) - 使用Layer过滤不需要应用效果的物体 - 禁用远处对象的后期处理(通过Distance参数) 6. 进阶技巧 - 配合Auto Focus扩展实现: - Raycast自动对焦 - 对象追踪对焦 - 动态景深过渡 - 通过脚本控制DoF参数实现: ```csharp // 动态设置焦点距离示例 void UpdateFocus(Vector3 targetPosition){ float distance = Vector3.Distance(camera.transform.position, targetPosition); depthOfField.focusDistance.value = distance; } ``` 7. 常见问题 - 模糊效果失效:检查URP Asset中的后期处理开关 - 边缘伪影:调整"High Quality Sampling"选项 - 性能骤降:检查是否同时启用多重抗锯齿(建议使用FXAA) 注意事项: 景深效果对GPU负载较敏感,在开放世界场景中建议仅在关键叙事节点启用,战斗场景可适当降低质量参数。建议在不同设备上测试参数组合,平衡视觉效果与性能消耗。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bunny Chen

来啊来让我发家致富,一毛钱可!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值