前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity通用渲染管线(URP)系列(十六)——渲染缩放(Scaling Up and Down)

Unity通用渲染管线(URP)系列(十六)——渲染缩放(Scaling Up and Down)

作者头像
放牛的星星
发布2021-01-11 15:01:57
4.1K0
发布2021-01-11 15:01:57
举报
文章被收录于专栏:壹种念头壹种念头

目录

 1 可变分辨率

 1.1 缓冲设置

 1.2 缩放渲染

 1.3 缓冲大小

 1.4 片段屏幕UV(Fragment Screen UV)

 1.5 缩放Post FX

 1.6 逐相机渲染缩放

 2 重新缩放

 2.1 当前方法

 2.2 重缩放LDR

 2.3 双三次采样(Bicubic Sampling)

 2.4 只有双三次上采样

本文重点内容: 1、通过滑动条调整渲染缩放 2、支持逐相机的不同程度缩放 3、在所有后处理之后重新缩放最终目标

这是关于创建自定义脚本渲染管道系列教程的第16部分。它是关于将渲染分辨率与目标缓冲区大小解耦的。

本教程是CatLikeCoding系列的一部分,原文地址见文章底部。

本教程使用Unity 2019.4.16f1制作。

(比较不同的渲染缩放)

修改 我在上一教程的末尾添加了一个新部分:4.5固定非标准相机。当渲染目标纹理使用中间缓冲区时并且没有post FX时,删除了CopyTexture的使用。

1 可变分辨率

应用程序一般以固定的分辨率运行。一些应用程序允许通过设置菜单更改分辨率,但这需要完全重新初始化图形。一个更灵活的方法是保持应用程序的分辨率不变,但改变相机用于渲染的缓冲区的大小。这将影响整个渲染过程,除了最终绘制到帧缓冲区。此时的结果将被重新缩放以匹配应用程序的分辨率。

通过减少缓冲区的大小,可以减少片段的数量,从而提高性能。例如,可以对所有3D渲染执行此操作,同时使UI保持全分辨率。还可以动态调整比例,以保持可接受的帧频。最后,我们还可以将缓冲区的大小增加到超采样,从而减少由有限分辨率引起的混叠失真。最后一种方法也称为SSAA,代表超采样抗锯齿。

1.1 缓冲设置

调整渲染比例会影响缓冲区大小,因此我们将为CameraScaleSettings添加渲染比例的可配置滑块。应该有一个最小比例尺,我们使用0.1。将2用作最大值,因为如果使用单个双线性插值步骤重新缩放比例,高于2不会提高图像质量。相反,高于2会使质量变差,因为当最终采样到最终目标分辨率时,我们最终会完全跳过许多像素。

默认渲染比例应在CustomRenderPipelineAsset中设置为1。

(渲染缩放滑动条)

1.2 缩放渲染

从现在开始,我们还将追踪是否在CameraRenderer中使用缩放渲染。

我们不希望配置的渲染比例影响场景窗口,因为它们是用于编辑的。通过在适当时在PrepareForSceneWindow中关闭缩放渲染来实现此目的。

我们确定在Render中调用PrepareForSceneWindow之前是否应该使用缩放渲染。跟踪变量中的当前渲染比例并检查其是否不为1。

但是,我们应该把边界设置的更模糊一些,因为与1的非常微小的差异将不会在视觉上和性能上产生任何差异。因此,仅在差异至少1%时才使用缩放渲染。

从现在开始,在使用缩放渲染时,我们还需要使用中间缓冲区。因此,请在Setup中进行检查。

1.3 缓冲大小

因为我们的相机的缓冲区大小现在可以不同于Camera组件指示的缓冲区大小,所以我们需要跟踪最终使用的缓冲区大小。我们可以为此使用一个Vector2Int字段。

剔除成功后,在Render中设置适当的缓冲区大小。如果按比例缩放渲染,则按比例缩放摄影机的像素宽度和高度,并将结果转换为整数,向下取舍。

在安Setup中获取相机附件的渲染纹理时,请使用此缓冲区大小。

如果需要,还可以用于颜色和深度纹理。

最初尝试时不带任何Post FX。你可以放大游戏窗口,以便更好地查看单个像素,这使得调整后的渲染比例更加明显。

(没有Post FX 渲染缩放为1 Game 窗口放大)

小渲染比例会加快渲染速度,同时降低图像质量。大的渲染比例则相反。请记住,当不使用post FX时,调整后的渲染比例需要一个中间缓冲区和额外的绘制,因此会增加一些额外的工作。

(渲染缩放分别为0.25,0.5,1.5和2)

最终绘制会自动将比例缩放到目标缓冲区大小。我们最终得到了一个简单的双线性放大或缩小操作。唯一奇怪的结果是HDR值,它似乎破坏了插值。你可以通过上述屏幕截图中心黄色球体上的高亮看到这种情况。稍后我们将解决这个问题。

1.4 片段屏幕UV(Fragment Screen UV)

调整渲染比例会引入一个错误:对颜色和深度纹理进行采样会出错。你会看到有粒子变形的现象,这显然是由于屏幕空间UV坐标不正确而导致的。

(不正确的扰动 渲染缩放为1.5)

发生这种情况是因为Unity在_ScreenParams中放置的值与摄影机的像素尺寸匹配,而不是我们要定位的缓冲区的尺寸。我们通过引入备用_CameraBufferSize向量来解决此问题,该向量包含相机调整后大小的数据。

确定缓冲区大小后,我们将这些值发送到Render中的GPU。我们将使用与Unity用于_TexelSize向量的格式相同的格式,因此,宽度和高度的倒数紧随宽度和高度之后。

将向量添加到Fragment中。

然后使用它代替GetFragment中的_ScreenParams。现在我们可以使用乘法取代除法。

(正确的扰动 渲染缩放为1.5)

_ScreenParams也不包含倒数吗? 差不多。它的最后两个部分包含逆加1。额外的1可以为某些特定用途节省一个额外的开销,但是在我们的例子下,需要额外减去一些开销,因此我没有使用它。

1.5 缩放Post FX

调整渲染比例也会影响后置FX,否则最终会导致意外的缩放。最可靠的方法是始终使用相同的缓冲区大小,因此我们将其作为新的第三个参数传递给CameraRenderer.Render中的PostFXStack.Setup。

PostFXStack现在需要追踪缓冲区大小。

它必须在DoBloom中使用,而不是直接使用相机的像素大小。

因为Bloom是与分辨率有关的效果,所以调整渲染比例会改变外观。仅需几次Bloom就可以轻松观察到这一点。减小渲染比例将使效果变大,而增大渲染比例将使效果变小。具有最大迭代次数的Bloom似乎变化不大,但是由于分辨率的变化,在调整渲染比例时可能会出现脉冲。

(2次叠加的Bloom迭代,渲染缩放分别为0.5,1,和2)

尤其是如果逐渐调整渲染比例,则可能希望保持Bloom尽可能一致。这可以通过将Bloom金字塔的起始大小基于相机而不是缓冲区大小来实现。让我们通过添加一个可忽略BloomSettings渲染比例的开关来使其可配置。

如果应忽略渲染比例,则PostFXStack.DoBloom将像以前一样以相机像素大小的一半开始。这意味着它不再执行默认的下采样至一半分辨率,而是取决于渲染比例。最终的bloom结果仍应与缩放后的缓冲区大小匹配,因此将在末尾引入另一个自动下采样或上采样步骤。

现在忽略渲染比例进行Bloom时,一致性会更高,尽管在非常低的比例下,它看起来仍然有所不同,仅仅是因为处理的数据很少。

(Bloom忽略渲染缩放,渲染缩放分别为0.5,1,2)

1.6 逐相机渲染缩放

我们还可以让每个摄像机使用不同的渲染比例。例如,单个摄像机始终可以以一半或两倍的分辨率渲染。这可以是固定的(覆盖RP的全局渲染比例),也可以应用在最上层,使其相对于全局渲染比例。

将渲染比例滑块添加到CameraSettings中,其范围与RP资产相同。还添加一个渲染比例模式,可以通过新的内部RenderScaleMode枚举类型将其设置为继承,乘法或覆盖。

(渲染缩放模式)

要应用每个摄像机的渲染比例,还应给CameraSettings一个公共的GetRenderScale方法,该方法具有渲染比例参数并返回最终比例。因此,根据模式的不同,它要么返回相同的比例,相机的比例,要么两者相乘。

在CameraRenderer.Render中调用该方法以获取最终的渲染比例,并从缓冲区设置中传递该比例。

如果需要的话,我们还要限制最终的渲染比例,使其保持在0.1~2范围内。这样,可以防止缩放过小或过大。

由于我们对所有渲染比例使用相同的最小值和最大值,因此将它们定义为CameraRenderer的公共常量。我只显示常量的定义,而不是替换CameraRenderer,CameraBufferSettings和CameraSettings中的0.1f和2f值。

(不同的相机不同的渲染缩放)

2 重新缩放

使用非1的渲染比例时,除了最终绘制到摄影机目标缓冲区外,其他所有事情都以该比例发生。如果未使用Post FX,则这是一个简单的Copy,可重新缩放为最终大小。当Post FX处于活动状态时,它也是最终绘制,它也隐式地执行缩放。但是,在最后DrawCall期间重新缩放会带来一些不利影响。

2.1 当前方法

我们当前的重新缩放方法会产生不希望的副作用。首先,正如我们之前已经注意到的,在向上或向下缩放比1亮的HDR颜色时,总是混叠的。插值仅在LDR中执行时才能产生平滑结果。HDR插值所产生的结果仍然大于1,根本不会出现混合效果。例如,零和十的平均值为五。在LDR中,似乎0和1的平均值为1,而我们希望它为0.5。

(颜色插值 有和没有HDR,渲染缩放为0.5和2)

在最后一次Pass期间重新缩放的第二个问题是会将颜色校正应用于插值颜色而不是原始颜色。这可能会引入不需要的颜色带。最明显的是在阴影和高光之间进行插值时出现中间色调。通过对中间色调应用非常强的色彩调整(例如将它们设为红色),可以使这一点变得非常明显。

(很强的红色调 渲染缩放为0.5,1和2)

2.2 重缩放LDR

尖锐的HDR边缘和颜色校正伪影均由在颜色校正和色调映射之前对HDR颜色进行插值引起。因此,解决方案是同时在调整后的渲染比例下进行,然后再进行另一个CopyPass,以重新调整LDR颜色。向PostFXStack着色器添加新的最终重新缩放过程,以完成此最后一步。它只是一个Copy Pass,也具有可配置的混合模式。像往常一样,为其添加一个条目到PostFXStack.Pass枚举。

现在,我们有两个final Pass,这要求我们向DrawFinal添加一个pass参数。

现在,我们需要在DoColorGradingAndToneMapping中使用哪种方法取决于我们是否正在使用调整后的渲染比例。可以通过将缓冲区大小与相机的像素大小进行比较来进行检查。检查宽度就足够了。如果它们相等,我们将像以前一样绘制最终的Pass,现在以Pass.Final作为参数显式地绘制。

但是,如果需要重新缩放,则必须绘制两次。首先获得一个与当前缓冲区大小匹配的新临时渲染纹理。当我们在其中存储LDR颜色时,就可以使用默认的渲染纹理格式。然后在最终Pass模式下进行常规绘制,将最终混合模式设置为One Zero。之后,使用最终的重新缩放的Pass执行最终绘制,然后释放中间缓冲区。

通过这些更改,HDR颜色也似乎可以正确插值。

(LDR中重缩放 渲染缩放为0.5 和2)

而且颜色分级不再引入渲染比例为1时不存在的色带。

(色彩校正后的重缩放;强烈的红色中间调;渲染比例0.5和2。)

请注意,这仅在使用post FX时解决此问题。因此没有颜色分级,我们也假设没有HDR。

2.3 双三次采样(Bicubic Sampling)

降低渲染比例时,图像变成块状。我们添加了一个选项,可以使用双三次上采样进行Bloom,以提高其质量,并且在重新缩放到最终渲染目标时也可以这样做。为此,将一个开关添加到CameraBufferSettings中。

(双三次重缩放开关)

向PostFXStackPasses添加一个新的FinalPassFragmentRescale函数,以及一个_CopyBicubic属性以控制它是使用三次采样还是常规采样。

更改最终的重新缩放比例,以使用此功能代替复制功能。

将属性标识符添加到PostFXStack,并使其追踪是否启用了双三次缩放,这是通过Setup的新参数进行配置的。

在CameraRenderer.Render中传递缓冲区设置。

并在执行最终重新缩放之前,在PostFXStack.DoColorGradingAndToneMapping中适当地设置着色器属性。

(双线性和双三次缩放;渲染缩放为0.25)

2.4 只有双三次上采样

双三次缩放在放大时始终可以提高质量,但是在缩小时,差异必须不太明显。它对于渲染比例2总是无用的,因为每个最终像素都是四个像素的平均值,与双线性插值完全相同。因此,让我们用以下三种模式之间的选择替换BufferSettings中的开关:关闭,仅向上以及向上和向下。

在PostFXStack中更改类型以匹配。

最后更改DoColorGradingAndToneMapping,以便双三次采样仅用于上下模式或仅向上模式(如果我们使用缩小的渲染比例)。

(只有双三次的上采用)

欢迎扫描二维码,查看更多精彩内容。点击 阅读原文 可以跳转原教程。

本文翻译自 Jasper Flick的系列教程

原文地址:

https://catlikecoding.com/unity/tutorials

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 壹种念头 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档