动态分辨率
动态分辨率可减轻 GPU 的工作负载,从而有助于保持稳定的目标帧率。高清渲染管线 (High Definition Render Pipeline, HDRP) 使用动态分辨率来降低主渲染通道使用的渲染目标的分辨率。为此,如果平台支持硬件动态分辨率,则 HDRP 将使用硬件动态分辨率,否则将使用软件版本。主要区别在于,对于硬件动态分辨率,硬件将一直处理渲染目标,直到后缓冲区 (back buffer) 达到缩放的大小为止。这意味着可以更快地清除渲染目标。
要在项目中使用动态分辨率,必须在 HDRP 资源中启用动态分辨率。在 HDRP 资源的 Inspector 中,导航到 Rendering > Dynamic Resolution,然后启用 Enable 复选框。如需了解如何自定义 HDRP 资源的其他全局动态分辨率属性,请参阅 HDRP 资源文档的动态分辨率部分。 此外,每个需要执行动态分辨率的摄像机都需要在摄像机组件上设置复选框 General > Allow Dynamic Resolution。
启用动态分辨率时,HDRP 会分配渲染目标来适应可能的最大分辨率。然后,HDRP 相应地重新缩放视口,使其能够以不同的分辨率进行渲染。在每帧结束时,HDRP 会将缩放渲染的结果升级以匹配后缓冲区 (back buffer) 分辨率。无论 HDRP 使用哪种方法(硬件还是软件)来处理动态分辨率,都仍然使用软件方法来扩展结果。HDRP 使用的方法是在 Upscale Filter 中定义的。
使用动态分辨率
要在项目中使用动态分辨率,必须在 HDRP 资源中启用动态分辨率,然后为每个要用于的摄像机启用动态分辨率。为此需要执行以下操作:
- 在 HDRP 资源的 Inspector 中,选择 Rendering > Dynamic Resolution,然后启用 Enable 复选框。如需了解如何自定义 HDRP 资源的其他全局动态分辨率属性,请参阅 HDRP 资源文档的动态分辨率部分。
- 对于您希望执行动态分辨率的每个摄像机,请找到 General 部分并启用 Allow Dynamic Resolution。
动态分辨率不是自动的,因此需要手动调用 DynamicResolutionHandler.SetDynamicResScaler(PerformDynamicRes scaler, DynamicResScalePolicyType scalerType)
函数。
策略类型可以是下列其中一个:
DynamicResScalePolicyType.ReturnsPercentage
:DynamicResolutionHandler 期望scaler
返回屏幕百分比值。设置的值将限制在 HDRP 资源中设置的最小百分比和最大百分比之间。DynamicResScalePolicyType.ReturnsMinMaxLerpFactor
:DynamicResolutionHandler 期望scaler
返回一个因子t
,该因子的取值范围是 [0 ...1] 并且将用作 HDRP 资源中设置的最小和最大屏幕百分比之间的 lerp 因子。
下面的示例将说明如何调用此函数。在实际生产环境中,可以根据应用程序的性能调用此函数。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
public class DynamicRes : MonoBehaviour
{
public float secondsToNextChange = 1.0f;
public float fractionDeltaStep = 0.1f;
private float currentScale = 1.0f;
private float directionOfChange = -1.0f;
private float elapsedTimeSinceChange = 0.0f;
// 一个简单的策略示例,每 secondsToNextChange 秒钟缩放一次分辨率。
// 由于此调用使用 DynamicResScalePolicyType.ReturnsMinMaxLerpFactor,因此 HDRP 在以下上下文中使用 currentScale:
// finalScreenPercentage = Mathf.Lerp(minScreenPercentage, maxScreenPercentage, currentScale);
public float SetDynamicResolutionScale()
{
elapsedTimeSinceChange += Time.deltaTime;
// 等待 secondsToNextChange 秒,然后请求更改分辨率。
if (elapsedTimeSinceChange >= secondsToNextChange)
{
currentScale += directionOfChange * fractionDeltaStep;
// 当 currenScale 达到最小或最大分辨率时,这会切换分辨率更改的方向。
if (currentScale <= 0.0f || currentScale >= 1.0f)
{
directionOfChange *= -1.0f;
}
elapsedTimeSinceChange = 0.0f;
}
return currentScale;
}
void Start()
{
// 绑定上面定义的动态分辨率策略。
DynamicResolutionHandler.SetDynamicResScaler(SetDynamicResolutionScale, DynamicResScalePolicyType.ReturnsMinMaxLerpFactor);
}
}