为期四天的腾讯游戏开发者大会(Game,简称TGDC)将于12月7日在线上举行。
在今天的主题演讲中,来自腾讯NExT 的中级技术美术师谢园以“向阳而生——光线追踪项目应用”为主题,分享了NExT 探索和使用光线追踪技术的方式与方法。
不断探索和创新玩法的NExT工作室,可以说是腾讯旗下相当的存在。 就在去年,他们发布了一款独特的人机合作战术射箭游戏《重生之刃》。 在此前发布的预告片中,他们展示了使用虚幻4引擎和RTX光线追踪技术所实现的惊人画面效果。 就整体视觉效果而言,本作的表现丝毫不逊色于当今的主流大作。
以下是手游整理的部分讲课记录。 为了提高阅读体验,对内容进行了删减和调整:
大家好,我是NExT 的谢园,明天有机会跟大家聊聊光线追踪。
真实世界成像
首先,在我们了解光线追踪之前,我们想看看它的光照在现实世界中是如何工作的。
我们现在听到的画面,一般我认为人眼应该不会直接看太阳吧? 或者看看一些光源。 大多数情况下,光线是直接从阳台或门口射进来,射进来后会穿过墙壁或物体,经过一些二次锐降和三次锐降,这样随着光的能量逐渐衰减,大部分那个时候我们今天听到的就是这样一个画面。
那么我们从微观的角度来看一下这个灯是如何工作的。 假设一束光打在一个平面上,那么此时的平面,从自然界的角度来看,当我们将它无限放大时,会发现它的表面并不是那么完美和平坦,所以它的表面会有很多小的起伏在表面上,我们称之为微表面。
光线射到微表面后,会随着凹凸不平向不同方向反射。 在用笔记本模拟自然界中的一种光时,比如我们今天看到的右图。
这是一个非常简单的场景,一个小房间,里面有一盏灯。 这样一来,这盏灯的光源就向四面八方发散了。 我们可以想象,每一束光射到周围的墙壁后,由于墙壁的表面不平整,它会发散更多的二次回退。 第二次坠落后,它撞到了一些椅子、地面和屋顶。 每次它接触到一个平面,它都会进行更多的回调。
这样一来,我们可以想象,这样的计算量,虽然是非常庞大的。 所以一般我们在模拟这样的光照情况的时候,我们之前都是以离线渲染的形式呈现出来的。
栅格化渲染
现在我们再想一想,如果我们实时渲染场,怎么呈现这样自然的情况呢? 这时候我们就不得不引入一个概念——光栅化。
那么哪些是光栅化的? 虽然我们可以想象,当我们用嘴巴看到一个屏幕时,我们关注的所有内容都是屏幕中的物体,所以这个时候,我们会对屏幕空间进行裁剪。
也就是屏幕外的东西,我们暂时先不去考虑它的一些预估,然后我们把屏幕上这个三维物体的信息投射到屏幕的每一个像素上。 同时,在整个三维场景上,将转化为画面的信息进行分类。 比如有一些法线信息,有一些深度信息,有一些ID信息等等。
后面我们渲染的时候,会调用内存中保存的不同信息进行合成操作,这样最后就是我们看到的,最终的画面效果。
通过刚才的简单描述,我想大家应该能明白,这些方法最大的优点就是速度快,特别快。 因为它会去掉很多不可见的信息,比如屏幕外的信息不算在内; 其次,它会将大量的三维信息转化为屏幕像素作为估计值,这将大大节省大量的计算量。
但从另一个角度来看,这种方式已经大大削弱了一些信息,以还原一些本应在真实场景中呈现的疗效。 所以很多基于化学的渲染,或者一些好的效果,比如屏幕外的一些反射等等,在光栅化渲染下是无法很好渲染的。
光线追踪细节的表现
下面我们来看一段“重生边缘”项目的演示视频。 在此视频中,我们可以看到光线追踪开启和关闭之间的区别。 所以你看到右上角这个红色的LOGO,当RTXON代表此时光线追踪已经开启,代表此时光线追踪已经关闭。
目前我们可以看到此时RTX,也就是光线追踪已经关闭了。 所以当RT关闭时,你可以在地面上看到水池中的反射信息。 由于屏幕空间的限制,反射的信息量很小,很多屏幕外的信息无法正确反映。 .
我们在RTXON的时候反映了很多屏外信息。 你在这里看到的是带刺铁丝网的投影。 光线追踪下投影的疗效来自于我们的铁丝网是用 纹理制成的。 因此,光线在追逐时,跟随光源与被投射物体的距离有近有远,具有半影效果。
当我们关闭光追时,我们会发现此时的投影是清晰的,而这对于我们在自然界中观察到的物体来说可能不是很正确。 随着物体投射距离的变长或变短,它的影子会产生逐渐扩散的半影效果,这是在非RT条件下看起来不真实的一种表现。
这里还有一个池塘,也在阴影之下。 通过池塘的倒影光的反射和光的折射的例子,我们也可以看到天空中的一些信息,即使我们的屏幕上没有显示天空。
反之,关闭后是黑亮的,所以这是光线追踪带来的比较大的视觉差异。
一般我们在设计一些光线追踪场景的时候,也会考虑到一些情况,比如夜间,或者一些反光的金属物体,因为这样也更容易理解光线追踪。
这是人物在动态光投射下的阴影效果。 这时候RT是关闭的,所以你会发现它的影子从近到远总是比较立体锐利。
相反,RT打开后,有半影效果,动态物体的半影效果尤为显着。 大家可以看看平时走在路灯下发现自己的影子有什么治疗作用。
所以在整个场景中,我们尽可能的使用了一些动态光,然后是动态物体,然后是反射,更多的来创建光线追踪,呈现出一些独特的效果。
光线追踪渲染
通过刚才的视频,我们听到了RT在实际游戏项目中的一些介绍。 这时候,我们将回到我们最初的话题,即光线追踪是如何渲染的。
文章开头我提到了我们自然界的光是从光源开始的,对遇到的物体做了一次两次这样的回调。 这种光线追踪正好相反。 它从我们的相机投射为射线。 当相机在我们的 3D 场景中与某个物体的表面相交时,它也会相应地进行一些回调。 .
经过多次回调,可以溯源到物体甚至光源,然后这些信息依次落到我们的耳朵里,就是整个光线追踪路径的一个循环。 可以知道光线追踪有个的概念,看左图。
当我们逐渐增加回调的次数时,我们会发现,每减少一次,回调的次数和次数都有很大的提升和变化。 所以在实时渲染领域,虽然我们已经做了从屏幕开始的光线追踪渲染方式,但它的预估量还是比较大的。
这也是为什么光线追踪一直无法在实时渲染领域落地,一直是促使其在实际项目中大量推广的诱因。
GPU改进带来技术革新
现在我们可以看这张图,这是过去30年CPU和GPU的整个发展历程。 下面白线是CPU性能的提升,上面红线是主板GPU的提升。 从这张图我们可以很明显的看出我们GPU的发展速度远远超过了CPU的提升。
特别是在2018年,谷歌发布了DXR,一种基于RT的API结构。 同年,还推出了RTX主板。 我们之前的主板还是GTX。 2018年,RTX主板终于出现了。
那么这款主板和以往的主板有什么区别呢? 它采用了基于光线追踪硬件加速的内核,所以从RTX主板开始,我们可以真正将光线追踪应用到实时渲染领域。
由于光线追踪应用于实时渲染领域,我们可以在它前面应用一些原本基于离线渲染和化学的折射、反射和焦散等效果。
在我们的实际项目中,光线追踪一般有四种方式呈现,一种是光线追踪AO,包括它的阴影,包括它的反射,还有它的GI。
光线追踪的优势
下面我们就来一探究竟,在游戏中光追到底能给我们带来什么。
这是从游戏屏幕截取的屏幕截图。 我们可以注意红色箭头所指的方向。 这是一个池塘和一面全身镜。 我们想看看我们把它赶走后的变化。
(光追关闭前)
(光线散去后)
所以通过对比这张图,你很容易发现,当它左边的蓝色围栏在非RT条件下渲染得不够准确和完整时,包括下面的池塘,虽然它上面有一个红色的广告牌,而当它倒映在屏幕空间中,由于看不到广告牌,因此无法正确反映其在海面上的倒影。
与RT相比,它可以显示很多细节,包括一些精确的位置。
这也是我们在游戏开发中经常会遇到的一种情况,就是我们会在屏幕空间之外进行反射,有时候我们会加一个反射球,那么这个东西,中间的红球,它的主要作用就是捕捉将当前3D场景根据其位置中心在其直径范围内的一些信息,烘焙成图形。
这些方式填补了一些屏幕空间反射无法呈现的信息,其弊端也很明显。
第一个,因为自身估计的准确性,不能很准确的显示反射位置; 二是这张图本身的规格也是有限的,为了尽可能降低内存开销,所以它反映的内容也比较模糊。
同时,当我们在游戏场景中大量采用这种技术时,主板上的内存性能开销也是比较大的。 而如果我们在这么大的场景下使用RT反射,在这种情况下,我们看到的内容的准确性和清晰度会有很大的改变,但也会降低一些内存开销。
下图是一个动态物体的反射显示。
我们知道游戏中动态人物的一些反射,前面说了,没办法,因为它只能抓取一些静态的物体,所以动态物体的时候,只能靠一些屏幕空间反射来支持一些,比如正如今天对大海的一些疗效。
那么我们看RT开启后,连接动态物体时,它的投影反射还是比较清晰可见的。
在下图中,我们可以看一下。 当整个海量AI的一个场景呈现在我们的视野中时,角色头上的材质是一样的。 在这种情况下,我们可以进行批量渲染,RT 反射渲染了这么多字符,我们仍然可以达到 50 fps。
所以对优化这块的性能也是很有帮助的,我们有一些整个大场景的效果图。
不知道大家有没有注意到下图中的问题。 这是屏幕空间AO的一个疗效。 当我们的视角从俯视变为平视时,木柱的AO会产生一种很奇特的效果。 现象。
那么为什么会形成这样的疗效,我们来分析一下。
我们往下看会发现木柱这边的AO是基于屏幕深度图的缓存估计的,也就是说它会比较当前物体前后的像素。 谁的深度更深,如果两者的深度差大于AO的采样直径,则认为前方物体对后方物体形成环境遮挡,导致AO。
所以正因为我们是俯视的角度,所以它的深浅差对比比较小,所以笔记本会误以为瓶子离地面比较近,从而形成这样一个错误的治疗效果。
如果我们稍微一个层次的去看,那么你会发现它的报错现象会稍微好一些。 这显然也是因为从这个角度来看,它的深度差异会比较大。 当超过我们的采样直径时,误认为被遮挡的AO关系会急剧下降。
这一点一目了然。 这是光线追踪的 AO。 它基于化学计算。 你会发现它呈现的AO的疗效是很正常的。
接下来我们来谈谈光线追踪阴影。
现在当光线追踪关闭时,角色的投影来自一束光。 我们为此光使用 CSM 投影。 虽然我们已经打开了,但是我们会发现他的袖口上,包括他的鞋子里面,还是不会有密度关系的,以至于校服飘在人身上,包括墨镜周围,也没有三-维度的感觉。
这就是光追的效果。 首先,他的衣服和头上的文胸之间的半影效果非常真实,包括头上的校服。 虽然它的长度很细,但是我们还是可以清楚的看到它。 你会在脊柱内侧看到它的一些投影,包括整个墨镜,变得非常自然,接近于我们真正的治疗效果。
这是基于光线追踪的阴影呈现的投影与传统投影的区别。
本篇介绍一款光追GI。
目前是一座简陋的小房子,上面挂着一个红球。 疗效是我们没有开启RT,所以整个场景只有两盏灯,一个是天光,一个是直射光。
从这张图我们可以看到,整个室外的效果是非常平坦的,因为它的漫反射不能很好的遮盖住,所以场景看起来没有体积感,比较平坦。
这是激活了RTGI的疗效。 你可以看看刚才的图片。 我认为这是非常不同的。 所以有GI和没有GI真的有很大的区别,所以我们可以切换到灯光模式来看看有GI的画面。
首先会在室外形成漫射护盾,提感立马降下来。 与此同时,我们中间的球之前是红色的。 光线追踪在经历了第一次下落和第二次下落后,就会给周围的一些墙壁或地面,甚至天花板带来一些球中的颜色。
大家可以看看右下角的参数。 我们现在使用的是它的回调。 虽然做了两次,但已经可以达到这样的疗效了。
这么说吧,我们在实际项目中并没有使用RTGI。
第一个原因是我们整个开发团队本身就有一个动态的GI系统; 二是开启动态GI后,我们需要面对的最大问题仍然是性能问题。 如果我们的性能不理想,那么我们可能会提高它的质量,但是提高质量之后,它的RT GI会有一些噪音,这也是我们暂时没有在项目中直接使用RTGI作为激励的原因。
光线追踪优化
虽然个人认为也是一个重点,就是光线追踪的优化。 因为光线追踪再好,也无法优化到我们需要的性能标准,虽然没有办法在真实的游戏项目中推广。
在这个场景中,我们可以看到它的两边各有一个全身镜,在它的一侧有一个纯银的管子。 现在让我们在这个场景中切换它的视角。 这里可以看到我们通过全身镜看旁边的纯银管。
这时我们发现了一个很奇怪的现象,就是灯管变黑了。 为什么? 因为,你可以想象,我们通过全身镜看到这个管子,我们是可以看到管子的。 首先,这已经是光的回调了,所以这就是我们下面听到的,当前的帧率也接近于我们输入的回调次数。 处于60帧的状态。
但是,如果我们想让全身镜上方的金属机身仍然有反光效果,这就得做两次,这就是为什么现在大家听到的是黑管,现在又提了两次。
现在金属管内的一些细节和周围的一些物体也能准确呈现出来,不幸的是,我们会发现它的帧率下降到了19帧左右。 好吧,我们继续把它的回调数减少到三个。
这时候画面虽然和之前没有太大的变化,帧率还是下降了不少,不过现在已经不到8帧了。
那么通过这么一个简单的演示,我们可以得出,当我们使用光线追踪反射的时候,随着它的减少,它的性能下降的非常厉害。
那么这就带来了一个问题,就是我们如何平衡这一点呢? 这时候我们可以在管道附近加一个反光球,让它捕捉到管道周围的一些静态模型信息,然后我们可以在第二次使用RT命令让渲染回落,有时这个反光球被用作视觉填充。
这不仅平衡了我们性能上的不足,也带来了更好的视觉展示。 所以通过这些方法,我们可以在很多金属比较多的地方使用,比如一些全身镜。
这个场景也是室外场景。 我们知道,无论你的反射有多高或多低,RT都会对反射做一些回调。
但是我们可以仔细想想。 如果我们遇到的物体的平面比较粗糙,当然,即使里面有一些反射,给我们带来的视觉感受也不是很大,所以这时候我们可以限制它使一个反射的值变大.
比如这张图,我们认为大于等于0.2的时候需要参与RT的反射,但是这就带来了第二个问题,因为对于一个美术制作人来说,怎么才能更准确呢? 你知道纹理大于等于0.2的地方在哪里吗? 是参加RT的反思吗?
所以这时候我们就可以做一个后处理材质,我们把所有大于等于0.2的区域都用这些红色的方式标出来。 这样美工朋友一眼就可以知道我在哪些地方参与了RT的反思,是否需要那么多地方进行反思。
同时这对我们来说也是一个性能控制,可以作为一个很好的预览。
现在你看到这个图是一个材质的节点图。
因为我们在整个项目中都采用了 流程,也就是说所有美工都不需要自己制作 ,只要TA制作的 可以直接调整参数就可以使用.
在这种情况下,我们父材质的一些功能是比较复杂和繁多的,我们可以想象一下,假设有一个场景,我们有一面全身镜光的反射和光的折射的例子,然后有一扇很华丽的门,比如有一扇门,用的是很复杂的材质,比如杯子,是用很复杂的材质做的,从穿衣镜里看杯子。
首先第一点就是反射上面的杯子像素点一定比较小; 而如果我们在反射上看到了所有的材质效果,还按照这么复杂的计算,视觉体验可能还不够。 大大的让我们心情大降。
在这种情况下,我们引入了RT的一个节点,也就是说我们从反射物体观察细节的时候,还没有做到完全全节点计算,要参与RT反射,我们只给出一些比较简单的PBR节点,比如这个值,会大大简化我们的计算效果。
那边有个例子,所以现在全身镜上站着三个角色。 虽然我们可以仔细看一下,但是在角色的衣服上已经减少了一些细节,我们叠加了一些细节贴图。 此刻,我们的RT是关机再开机。 黄色袜子的内部也由那些细致的纹理呈现。
但是这个时候我们会看到整个光线追踪反射需要的微秒数是4.46微秒,但是我们开启RT之后直接把反射上面的白衬衫里面的一些细节材质杀死了,不需要渲染了。
所以从画面来看,并没有太大区别。 但此时,其RT反射所需的微秒数增加到了4.1微秒。 今天只是一个小小的反例。 我们可以想象一下,如果所有的父材质都使用这个RT的一些优化节点,在很多大场景中,会为我们的很多性能优化提供一些节省下来的资源。
这一块是我们也用到了一些新的蓝图,在新的蓝图中经常需要用到,并且在这个新的蓝图中预置了一些RT的参数,然后我们就可以把这个新的蓝图以体积框的形式放上去。 在两个不同场景的交界处。
比如这样一个室外区域和一个室外区域,因为室外和室外的光照信息首先是不一样的,里面参观的一些物体的结构、密度、材质也可能有很大的不同,所以我们用这样的一个In这样两个不同的RT优化参数可以在不同的环境下切换。
这样就可以得到整个玩法的平衡,同时也可以满足一些视觉效果。
最后一部分列出了项目中常用的一些RT优化方法、一些命令和一些参数。 虽然总的来说,你不得不牺牲一些视觉细节来换取一些性能的提升,然后最后才能在两者之间找到一个平衡点。
我觉得无论是光线追踪还是我们传统的光栅化渲染,它们的目的似乎都是为了给我们带来一个好的画面,而既然我们采用了光线追踪,这将打开我们对现实世界的大门。 门。