DLSS 2.0 - 基于深度学习的实时渲染图像重建

CharlotteOlga 发布于3月前

上周我们NVIDIA正式发布了DLSS 2.0,DLSS的全称是Deep Learning Super Sampling,主要作用是通过Tensor Core硬件加速的深度学习对实时渲染的图片实现非常高质量的超采样,从而大幅提升游戏渲染的性能。大家可以先看看我上周的文章了解一下背景:

文刀秋二:DLSS 2.0 - 重新定义AI渲染 ​ zhuanlan.zhihu.com DLSS 2.0 - 基于深度学习的实时渲染图像重建

今年原本我会在GDC和GTC上做关于DLSS 2.0的一些技术向的讲座,但由于美国疫情爆发,所有的会议都取消了,原本要给的Talk也变成了云录制的方式。讲座的视频今天终于上线了,这一篇文章主要会把讲座的内容大致的翻译以及转换成文章的形式,给我的专栏再剪剪草。

听英文没问题的同学建议直接去下面的链接听我的Talk,应该会比读这篇文章容易一些,内容也会更全面一些:

DLSS 2.0 - Image Reconstruction for Real-time Rendering with Deep Learning ​ developer.nvidia.com

正文开始前,我再转发一波DLSS 2.0正式发布一周多以来网上的各种神评论:

With an RTX 2060, performance levels that are functionally identical to an RTX2080Ti are possible with DLSS at its Performance setting. That's incredible.

DLSS 2.0 is some black magic fuckery that doesn't feel like a compromise whatsoever, and is fucking incredible. It's some serious Magikarp to Gyarados levels of evolution.

This tech is straight up insane. I just tried the intro in Control with the latest patch. Ran 1440p output resolution, DLSS @ 720p and it looked crisp as fuck. Really couldn't pass an eye test between DLSS on or off.

Given the almost negligible quality downsides delivered by DLSS, these performance gains are nothing short of incredible. To be completely honest, DLSS improved image quality in many instances, making these performance gains almost unfathomable.

Bilibili的一个Up主做了个好玩中文测评: N卡神秘功能实测,2千元显卡玩出8千元的效果?DLSS 2.0实测

好了,现在进入正题。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

为什么要研究DLSS

DLSS 2.0 - 基于深度学习的实时渲染图像重建

我们认为次世代的实时渲染技术,更好的图像重建和超采样是必须的。GPU的性能会随着每一代架构的更迭增加,然而人们对真实世界的光线以及物理的模拟对GPU性能的需求却增加的更快。实时光线追踪,基于物理的着色\模拟,VR渲染,8K显示器,这些元素加在一起早早的把这个时代的摩尔定律甩过了几条街。降低渲染分辨率,并且快速的超采样可以说是大势所趋。(主机上盛行的Checkerboard Rendering就是很好的例子)。

同时RTX GPU里的Tensor Core有110TFlops的针对深度学习任务的计算性能,我们理所当然的想要把这些性能也作用于图形应用程序中。

DLSS 2.0 四大特性

DLSS 2.0 - 基于深度学习的实时渲染图像重建

DLSS 2.0相比最初的DLSS实现了几个非常重要的突破:

  1. 画质极大提升,细节和锐度媲美、甚至超越原生分辨率
  2. 4倍像素超采样(540p到1080p,1080p到4K,每4个像素中有3个是通过超采样生成)
  3. 通用模型,一个神经网络适用于所有游戏(不同引擎,着色风格,分辨率都有很强的通用性)
  4. Inference开销减半

我的上一篇文章已经给出了一些图像质量和性能的分析和对比,这里再放一组和初代DLSS的对比。首先是用DLSS 1.0做720p到1080p的超采样:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

下面是用DLSS 2.0做 540p 到1080p的超采样,如果点开开大图应该不难发现DLSS 2.0用540p的图片作为输入,得到的结果的细节和锐度比DLSS1.0用720p作为输入还要优秀。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

接下来是原生1080p渲染,和540p的DLSS2.0差别很小,甚至会比540p的DLSS2.0结果模糊那么一些。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

最后贴两组放大的对比,应该都不难看出DLSS2.0在540p这种超低分辨率渲染的情况下,画面质量还是媲美甚至超越原生1080p:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

DLSS 2.0 - 基于深度学习的实时渲染图像重建

DLSS 2.0渲染加速

DLSS 2.0 - 基于深度学习的实时渲染图像重建

DLSS 2.0加速渲染的原理很简单。开启DLSS后,引擎的渲染会在1/2到1/4像素的低分辨率下运行。这意味着,一大半的像素级别的计算直接被粗暴的砍掉了。像素级别的计算通常包括GBuffer的渲染,动态光源、阴影的计算,屏幕空间的特效例如屏幕空间环境遮挡(SSAO)、屏幕空间反射(SSR),甚至实时光线追踪。这些计算通常也是一帧里面最耗费性能的部分、毕竟大部分的画面出色的游戏,像素计算是绝对的瓶颈(pixel bound)。

所以DLSS 2.0的加速多少,也直接取决于像素计算在多大程度上是性能瓶颈。通常来说,画面越好的3A大作,越会用更加耗费性能的渲染技术,像素也就会更大程度的成为瓶颈,而DLSS则会提供更大的加速!

在省掉的渲染计算之上,运行DLSS 2.0这个算法本身会引入一定的开销,这个开销通常是完全取决于分辨率大小的,不随场景内容而改变。下面这个表格展示了DLSS 2.0在不同GPU和不同分辨率下的开销。相比于DLSS 1.0,我们把这个开销减小了两倍以上。在2080Ti上,4K分辨率下也只有1.5毫秒,因为有Tensor Core的加速,这已经和普通的TAA非常接近了。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

超采样算法本身的运行开销小可以说是至关重要的,直接影响到最终渲染加速的大小。举个极端的例子,如果超采样过程本身和渲染一样慢,那么也这个超采样算法也就没有使用的意义了,直接渲染更多像素就好了。

介绍完了DLSS 2.0的特性,下面从技术的角度讨论一下DLSS和现有的图像超采样工作的对比。

Reconstruction基础

DLSS 2.0从本质上来说是一个图像重建算法(Image Reconstruction)所以在这里先举两个最基本的例子。假设我们需要绘制左边这个蓝色的曲线。但是我们并没有这个曲线的方程,我们能做的就只是在这个函数上离散的采样,然后通过这些离散的样本对原本的函数进行重建(Reconstruction)。在下面这个例子里,因为采样的频率低,最后重建的函数和原本函数差距也比较大,函数中间有很大一部分直接被所有样本漏掉了。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

在上面的例子里,如果把重建的质量和采样的频率直接相关,如果把采样率提高一倍,重建的质量也就明显提高了。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

渲染的过程中,采样和重建每一帧都在发生。屏幕空间所有的像素数量决定了采样的频率。渲染的过程中,每个像素会对场景中连续的几何信息进行点采样(Point Sampling),意思就是这个过程本身不存在任何的滤波(Filtering),这也是为什么在实时渲染中,渲染的结果会有锯齿(Aliasing)。最终渲染画面的质量和渲染的分辨率,也就是对场景采样的频率有直接关系。下图中可以看出三角形重建后的结果走样的很厉害。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

如果把采样频率提高4倍,三角形重建的质量也直接提高了很多。然而在渲染中,采样的频率,也就是渲染分辨率,和渲染的性能成反比。获得更高画质的同时,必定牺牲性能。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

所以DLSS尝试解决的问题,就是如何用低频率采样得到的样本重建出高频采样的质量。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

换句话说,DLSS意在通过更高效的样本利用率来提高渲染的“效率”,能在同样性能的情况下得到更好的画质,亦或者在画质相同的情况下,大幅度提升性能!

DLSS 2.0 - 基于深度学习的实时渲染图像重建

单帧超分辨率(Single Image Super Resolution)

DLSS 2.0 - 基于深度学习的实时渲染图像重建

单帧超分辨率是和DLSS非常相关的一个研究方向。尤其是跟着这两年深度学习的应用的热度,这个问题的state of the art也提高了很多,这个方向的研究也经常上国内公众号的头条,例如SRCNN,SRGAN,ESRGAN等等。所以也许不了解的人会马上以为DLSS也是和这一类工作同样的工作原理。

可是单帧超分辨率其实是个非常困难的问题,因为本质上需要生成低分辨率图像中完全不存在的信息。用神经网络解决这一类问题,本质上就是在训练集中学习到各种低分辨率的像素和高分辨率像素的一个对应关系。有了这个映射后,神经网络能做到比一般的基于插值(interpolation)的方法更好的效果。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

但尽管如此,这样生成出来的信息其实是完全基于训练集图片中的数据分布,而并不是对我们实际正在渲染的场景的采样。所以单帧超分辨率的结果经常会和原生分辨率渲染在风格和样式上 不一致 。对于DLSS来说,我们的目标是重建出和高分辨率渲染一模一样的结果,所以单帧超分辨率一类的工作对实时渲染来说很难适用。

下面就是一个例子,用单帧超分辨率超采样的图片和原生分辨率还是有不小的差别,树丛里的所有叶子都变肥了不少。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

下面对比一下DLSS 2.0,ESRGAN,以及原生分辨率渲染,首先是DLSS 2.0从540p到1080p的结果:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

ESRGAN是一个比较新的基于GAN的单帧超分辨率网络,之前还有人用它直接提升游戏内部的纹理分辨率。接下来看看直接用来做渲染超分辨率的结果:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

最后是1080p原生分辨率渲染的结果。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

如果放大到200%来看的话,应该可以看出ESRGAN的结果和原生渲染相比,少了很多细节,同时也并不和原生渲染一致。与此同时,DLSS2.0的结果里,每一根树叶都清晰可见,甚至细节比原生渲染还要丰富。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

多帧超分辨率(Multi-Frame Super Resolution)

DLSS 2.0 - 基于深度学习的实时渲染图像重建

另一类超采样的工作则是针对视频,或者手机摄影的多帧超分辨率。多帧超分辨率并不像单帧超分辨率那么的困难,因为我们不完全需要填补原本不存在的信息。有多个低分辨率图片的情况下,这个问题会可控很多,多帧合成的高分辨率图片往往在光学细节上的还原的质量上会比单帧超分辨率的高许多。

然而针对视频或者摄影的算法也并不太能直接搬过来用于实时渲染,原因有许多。1)在渲染中,我们可以用到的数据是比视频多很多的,我们可以计算每个像素精确的运动向量(motion vector),我们也可以有场景函数的精确采样,有HDR颜色,甚至像素的精确深度。不利用这些信息,设计出来的算法在效率和质量上都不会是最优的。2)许多视频超分辨率的工作是需要用时序上未来的图片来重建当前帧的图片的,因为实时渲染对延迟的要求,这也显然不适用。

然而有没有专门针对渲染的多帧超采样算法呢?当然有。

时序超采样(Temporal Super Sampling)

DLSS 2.0 - 基于深度学习的实时渲染图像重建

利用把渲染的样本分布在多个帧上,并且用这些多帧复合的样本重建出最终渲染的图片,这在实时渲染领域太司空见惯了。几乎所有引擎都在用的Temporal Antialiasing(TAA),或者游戏主机上非常流行的Checkerboard Rendering都是这么一个思路。

这一类算法利用了渲染图片的 时序连贯性(Temporal coherency) ,既渲染结果的帧与帧之间大体是连续的,发生高频变化的概率不高。也就是说,我们可以假设需要渲染的场景在上一帧和当前帧几乎一样。如果这个假设成立的话,我们大可以之间复用过去帧上对场景采样的样本来重建当前帧:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

这样做的好处是,每一帧的采样率非常低,所以渲染性能会有很大的提升,然而重建图像时的样本还都确实是对于场景函数的无偏采样,所以最终重建的图像质量也会和原生分辨率渲染非常一致。

然而天下哪有这等好事,实时渲染或者游戏的图片序列中几乎每一帧都有或多或少的变化,从角色动画,到动态光影,到粒子特效。直接复用过去帧的样本来重建当前帧的图片会使重建的结果中产生很大的错误。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

这种错误在渲染图片中会以延迟,或者鬼影(ghosting)的形式呈现出来。下面就是一个直接复用多帧样本渲染的错误例子。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

这也是为什么,所有实时渲染中的时序超采样算法,例如TAA,都有非常重要的一步去“纠正”过去帧中样本的错误。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

这一类算法需要首先检测过去帧和当前帧因为场景的变化导致的样本错误,然后在不影响画质太多的情况下,“合理”的纠正那些错误的样本。乍一看这简直是个计算机视觉问题,然而在实时渲染中这一步需要非常高效的完成。所以过去十几年,游戏开发者绞尽脑汁的发明了各种“启发式”的方法(Heuristics)。(我研究生时候一个老师的名言:什么是启发式,启发式就是不知道到底怎么解决就只能瞎猜)

目前解决这个问题效果最好,也最常用的Heuristic,叫做Neighborhood Clamping。是Epic的Brian Karis在14年的SIGGRAPH的一个实时渲染讲座里最先提到的。思路其实很简单,就是把过去帧采样的样本的值的范围,限制在当前帧像素周围3x3大小的Local neighborhood的所有样本的值的范围内。下图简单在一维的例子上解释一下这个过程:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

中间的示意图中,每一个红色的点都被Clamp到周围绿色点的范围内了。如果用“纠正”过的样本来重建最终图像,如右图所示,重建的结果中便没有太过于明显的错误了。

但是,用这个方法也经常会“过度纠正”,例如右图中高亮的两个样本,他们原本的确是正确的样本,但是因为这个算法,反而被过度纠正,反而变的不那么精确了。

Neighborhood Clamping的质量也直接和当前帧渲染的采样率相关,因为当前帧样本稀疏的话,意味着用于纠正过去帧样本的参考也更加低频,导致最终结果也会更加低频、模糊。下面的例子展示了如果在减少当前帧采样数量再用Neighborhood Clamping的话,最终重建的函数也会更加缺少细节。也就是说,在做超分辨率的时候,用这一类算法更加容易都是最终图片中的细节。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

下面用两张渲染的图片来解释这个问题。左边的图片用了Neighborhood Clamping,右边的没有用。非常明显,用了之后画面的细节程度大打折扣。然而不用的话,则会产生更严重的鬼影(Ghosting)问题。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

DLSS 2.0 - 基于深度学习的实时渲染图像重建

模糊的图片质量并不是用这一类Heuristics唯一的问题,很多时候还会产生更讨厌的时序上的不稳定性(Temporal Instability)。下面这个这个视频就是一个例子。视频中的内容是1080p原生分辨率渲染,然而因为场景中的纹理过于高频,导致出现了摩尔纹的现象。

DLSS 2.0 - 基于深度学习的实时渲染图像重建 https://www.zhihu.com/video/1229423259814182912

同样的,Temporal instability在渲染分辨率降低的时候,也就是做超采样的时候,会变的更加严重。下面的例子是用TAA的一个变种TAAU在540p渲染然后在1080p重建图片的结果。很明显,画面中的抖动幅度变大了,抖动的区域也变大了。

DLSS 2.0 - 基于深度学习的实时渲染图像重建 https://www.zhihu.com/video/1229422879176904704

为什么会出现这样的现象呢?下面我们把放大看一个抖动的区域,并且把每一帧的样本给可视化出来:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

很明显,在连续的4帧中,抖动区域的样本有很严重的摩尔纹。因为像素的采样pattern是uniform grid,有固定的采样频率,所以当场景的频率达到像素频率的Nyquist频率时,摩尔纹也是很难避免的。

不仅如此,Neighborhood Clamping在这种情况下基本完全无法正常工作了。尽管当前帧的样本在时间上的分布非常高频,但它们在空间上分布又非常低频。所以用了任何的clamping之后,基本上就把所有的过去帧的样本给丢弃了。

实时渲染超分辨率的难点

DLSS 2.0 - 基于深度学习的实时渲染图像重建

说了那么多,其实就想说明如果要把现有的学术界或者工业界的算法,无论有没有深度学习,直接用来解决实时渲染的超分辨率是有很多挑战的。

单帧的算法结果会模糊并且会和原生渲染不一致,而且帧间也经常会有抖动。

多帧的算法则需要用各种启发式的方法去解决各种过去帧和当前帧场景样本不一致的问题。这个Talk里我只提到了Neighborhood Clamping作为一个例子,然而类似的奇技淫巧还有很多,例如基于Luma变化的技术,基于motion大小的技术等等。最终图像的画质,很大程度受限于这些启发式技术有多鲁棒。但任何Heuristic的鲁棒性都是有限的,这也导致多帧的图像合成算法,包括常用的TAA和Checkerboard rendering都有局限。

DLSS 2.0 - 基于深度学习的多帧图像重建

DLSS 2.0 - 基于深度学习的实时渲染图像重建

DLSS 2.0首先也是一个基于多帧的图像重建技术。因为我们的目标是重建出和原生渲染一致的画面,所以基于用单帧的算法去“想象”不存在的信息是不适用的。

那DLSS 2.0和现有的实时渲染中的时序超采样有什么区别呢?DLSS2.0抛弃了人肉手调的启发式算法,用一个在超级计算机上数万张超高质量图片训练的神经网络来代替这些Heuristics。就像深度学习在几年前在计算机视觉领域超越了各种手调的特征提取算法一样,深度学习第一次在实时渲染中也非常合理的跑赢了图形领域的手调算法。

用DLSS 2.0重建的渲染图像序列达到了非常高的多帧样本利用率,这也是为什么只用四分之一的样本就可以重建出媲美原生分辨率渲染的图像质量的原因。

下面是DLSS 2.0的粗略架构图:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

那么接下来看看用DLSS 2.0渲染之前的摩尔纹场景,做540p到1080p超采样的效果。

DLSS 2.0 - 基于深度学习的实时渲染图像重建 https://www.zhihu.com/video/1229432221142433792

需要强调一下,上面是一个视频,不是一个图片!很明显,全程没有任何的抖动,甚至比原生分辨率渲染还要稳定很多!

最后再放两组DLSS 2.0和非基于深度学习的时序超采样算法的画质对比:

DLSS 2.0 - 基于深度学习的实时渲染图像重建

DLSS 2.0 - 基于深度学习的实时渲染图像重建

如果大家认为DLSS 2.0在540p的渲染分辨率下,得到的结果比原生1080p的细节还更加丰富的话,我只能说:“我同意!”

DLSS 2.0 引擎集成

文章的最后,我粗略的提一下引擎集成方面,想要知道更详细的集成方面的信息,建议直接听我的Talk。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

相信现在大家已经知道,DLSS 2.0并不是一个单纯的图像超分辨率算法。它是一个专门针对实时渲染应用的算法。所以引擎要集成DLSS 2.0,需要配合的作出相应的改动。但所幸改动的幅度远比类似Checkerboard rendering简单。

首先当然是引擎要把所有的像素着色工作在低分辨率执行,通常这些包括GBuffer渲染,动态光影,屏幕特效,光线追踪等。

其次,DLSS 2.0是一个融合了抗锯齿和超采样的算法。引擎现有的抗锯齿解决方案例如TAA需要被移除,然后DLSS需要被插入在后处理(post processing)之前,这样后处理可以处理抗锯齿后的平滑图片以避免各种artifact。

DLSS的输出会是一个高分辨率的图片,所以引擎需要超采样后的分辨率下计算各种后处理特效,例如景深,动态模糊,tonemapping以及渲染UI。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

我们现在提供了一个集成过DLSS2.0的虚幻引擎4branch,大家可以在下面ppt中的连接申请访问。这个branch可以作为集成的样例,也可以用与测试和体验DLSS2.0的画质,性能以及通用性。

DLSS 2.0 - 基于深度学习的实时渲染图像重建

写在最后

在我发表了 上一篇关于DLSS2.0的文章 后,评论里有小伙伴说:现在没有必要搞图形了,因为要被AI替代了。我想说DLSS的确是一个基于深度学习的算法,但与此同时他更是一个实打实的图形渲染算法。深度学习确实是一个有用的工具,但是要解决任何一个领域的问题,肯定要对这个领域和问题本身有足够深刻的理解,才能知道如何去用DL这个工具。

DLSS是第一个深度学习在实时图形领域的应用,但肯定不会是最后一个。我们也在积极的探索更多的可能性。觉得自己背景匹配,想参与相关工作或者实习的童鞋可以私信我。

查看原文: DLSS 2.0 - 基于深度学习的实时渲染图像重建

  • organicgorilla