首页 攻略 Epic中国首席引擎:让大厂抢先布局的UE5,核心技术都在这儿了

Epic中国首席引擎:让大厂抢先布局的UE5,核心技术都在这儿了

更新时间:2022-11-14 12:49:47 分类:攻略 浏览:179

UE5核心功能与开发路线解析。

整理/以撒

今年,UE5的新技术逐渐进入了游戏从业者的视野。 无论是官方发布的两次Demo,还是《黑神话:悟空》的新实机演示,都让很多人感到摩拳擦掌。

与此同时,你可能也注意到了很多制造商开始布局UE5。 举几个例子,腾讯天美的两款3A级开放世界项目、NExT Studios的火星题材项目、米哈伊尔的机甲开放世界项目,还有灵游坊的两款主机产品……等等。

看起来很有气势,但UE5的各项技术对我们来说似乎还毫无头绪。 ——那到底能做什么呢? 和以前相比有什么进步? 在具体过程中如何实现?

那么,这些硬核的技术细节可能谁也看不出来。 但是,是为新项目的引擎找到参考,还是制定新的学习目标,还是单纯地想聚在一起了解行业前沿知识,不妨往下咬一口。

今天,在腾讯游戏教室召开的第五届腾讯游戏开发者大会( tencentgamedevelopersconference,即TGDC )上,Epic Games China首席引擎开发工程师王祢(主要是

以下是整理后的共享内容。

你好。 今天主要介绍UE5的新功能。 当然,UE5有太多新功能,所以选择大家最感兴趣的Nanite和Lumen多说。

开发UE5时,我们主要有三个目标。 提高各方面的渲染质量,使数字世界更加动态。 这提高了整个虚拟世界的构建和表达上限。 同时希望提供更丰富、更易于使用的工具,提高开发和迭代效率,改善用户编辑和创造体验,也就是降低使用门槛。

与UE4相比,UE5有了很大的改善。 主要包括Nanite和Lumen等渲染技术、用于构建整体大世界的工具以及用于渲染大量对象以生成Proxy Mesh的基础技术。

在协作方面,管理大量资产的性能、编辑器和用户体验、新一代的一些动画技术Chaos、网络同步的物理系统、以及一些新的模块、游戏框架、AI集群系统、更

01

Nanite

今年5月,我们在古代山谷Demo中展示了UE5 EA版本的主要功能。 首先,是我们的主要功能之一Nanite。 这是一种新的Mesh表示形式,它是一种虚拟微曲面几何体,消除了以往建模对许多细节的限制。 在EA版本中,Nanite还有很多功能不完善,今后会逐渐改善。

古代河谷Demo

现在,Nanite可以实际用于制作电影级资产——数百万,甚至上亿面的模型,也可以直接读取照片建模、Zbrush雕刻的高分辨率、CAD数据等引擎,高效渲染。 我们测试过数万到十几万个百万面以上的实例,如果每个都能在view上看到的话,像2080s这样的GPU可以达到60fps、1080P左右的分辨率。

目前,Nanite支持的平台主要是新一代主机和PC。 与去年我们推出的Lumen in the land of Nanite相比,该技术的质量和效率提高了很多。 例如,磁盘的编解码效率和压缩、灯光烘焙支持、可破碎物体支持、自动生成用于灯光跟踪场景和物理碰撞的一些减面,以及支持高质量的备用Proxy mesh。

另外,通过该方式,还可以利用解析微分法决定像素误差,使误差肉眼看不见。 最后,我们还高效地支持了多灯光投影。 整个Nanite管线是基于GPU driven管线生成的。 主要过程分为这些部分进行说明。

为了有效地从场景中移除许多对象,必须将所有场景数据发送到GPU。 其实从4.22开始,引擎逐渐在不影响上层使用的情况下,在下层进行了改进,使渲染器成为retained mode,维持了完整的GPU scene,Nanite在此基础上做了大量的新工作。

在Nanite上生成集群

接下来,我们将简要介绍Nanite的工作原理。 首先在导入模型时,进行128面集群的剪切处理等预处理。 有了这些集群,当距离变得很远时,可以同时在每个集群之间切换。 这样可以避免肉眼看不到切换lod引起的误差和没有crack,同时可以对这些不同级别、细节的集群进行流处理。 这其实是Nanite最重要的部分。

cluster的生成主要分为以下步骤。 首先,当原始的mesh lod0数据进来时,创建graph partition。 例如,那个条件是想尽量减少共享的边界。 这样,在lock边界进行减面处理时,减面的质量会变高。

二是希望这些面积尽量均匀,大小一致。 这样,在屏幕上投影lod计算误差处理时,所有cluster或cluster group都会一致处理。 我们将其中一组集群合并成一个集群组,再次在“lock边界尽可能少,面积尽可能均匀”的条件下找出,一组集群生成group,并锁定这个group内集群的边缘

减少面条后,我们可以得到新的cluster误差。 我对减少了这个面的group重新做cluster分类。 此时,集群的数量在同一个group中实际上是一半。 然后,计算每个新集群的误差。 请注意,这个过程是循环的。 递归到最终值,instance,每个模型只生成一个cluster。 这里有重要的一点。 我们通过减面生成各集群时,通过减面算法( QEM )得到该集群的误差值并存。

另外,我们保存group的误差值。 该值实际上是更精细级别的cluster group的cluster的最大误差值和在我的新级别出现的每个cluster的误差值取maximum得到的值。 这样,我可以保证,每当这个集群被合并时,去上一个集群中的集群减少面时的误差值,永远从细微处逐渐上升到细微处。

也就是说,我从最根的集群慢慢前进到最细的集群,里面的error一定会按照降序排序。 这是很重要的。 这是因为,之后选择culling和lod时,保证正好在由一个cluster构成的DAG中。 由于cluster将合并组,因此在组生成变得松散后,下一个级别将具有共享的cluster。

如果有按照这个降序排列的误差,我可以保证这个DAG上有漂亮的cut,我的边界一定是跨越lod的cluster group的边界。 最后,针对该生成的各lod等级的cluster分别生成bvh,将所有lod的cluster的bvh的root乘以总bvh root。

当然,这里有很多额外的处理,但现在没说。 我在考虑进行流处理时的寻呼处理。 因为这个分页符可能会给cluster group带来剪切,所以有cluster group,还有几个group partition的概念,这里不细分。

另外,关于一些微小物体远离后的情况,我们减少到了最后一类cluster。 其实还有128个面。 如果场景中非常小的东西在远处,这又是模块化的结构。 我们不能直接呼叫那个。 在这种情况下,我们有另一种Imposter atlas方式。 在这里我也不往下说了。

Nanite裁剪过程

接下来,我们来看一下整个Nanite通过GPU进行修剪的整体流程。 它分为两次修剪和光栅化。 我们在上一帧的HZB中进行了对象级别的实例削减,然后进行了按级别的、刚才说的bvh的集群的按级别削减。

最后裁剪到那个bvh的叶的节点,其实是刚才说的cluster group,对其中的cluster进行裁剪。 裁剪结束后,我们有一个特殊的光栅流程,然后我们可以得到新的Depth Buffer,重构HZB,对这个新的HZB进行再裁剪一次。

前面的HZB的可见性可以通过使用在前面帧中可见的实例来进行,完成后形成新的HZB,将在前面帧中看不到的东西再进行一次,可以保守地确保没有任何问题。

重新光栅化后,在新的可视化缓冲器中生成,从可视化缓冲器经过材质路径,最终集成到g缓冲器中。 具体进行culling时,存在几个问题。 例如,如刚才在创建cluster时所述,要创建cluster group的bvh结构不知道在CPU上有多少层。

也就是说,如果我要做的话,CPU必须发行足够多的dispatch。 此时,例如小的对象中,空的dispatch变多,该情况下GPU的利用率也降低。

所以我们选择了persistent culling这个方法。 使用永久标题进行查询。 也就是说,只做一次dispatch,打开足够多的线程,用简单的多生产者、多消费者的任务队列填满这些线程。

当这些线程从队列中运行时,每个node将生成新的node (即bvh node、Push back )并返回新的,同时进行外涂层级剔除。 在可见的children列表中,正在处理此列表直到任务为空。

这里的处理分为几个类型。 首先在第一个node中,只有我们开始构建的bvh的节点,是我剔除后到叶的节点,里面是cluster group,下一个层次是这个group中的所有cluster culling。 最后,cluster并行独立,判断自己是否被culling了。 这里其实和刚才lod选择的条件一模一样。

还记得我刚才说的error的单调性吗? 在这里的cluster中,所有的lod都是混合的,所以在我们的每个cluster上并行处理时,我不知道父母的关系是什么样的,但是我在每个cluster上储存了自己的误差,以及我整个group在父母层面上的最大误差

同样,和我一起有cluster group的这些节点。 如果它在我的上一个级别,也就是粗的级别,那个错误是不够的,所以有上一个级别lod的整个组将被丢弃,下一个级别将被选中。

但是,下面可能有——其实误差太大了。 如果那个误差足够大,那就意味着它在另一个更精细的地方,一定属于另一个cluster group。 因此,它还在下一个类的cluster group上有边界,与下一个类的cluster group边界相连时将没有接缝。 整个cluster的选择就是这样并行进行的。

同时,与自己的cluster group相对应的parent,就像刚才说的那样,一定会被删除。 这样,我们可以以cluster group为边界对接不同lod级别的cluster,将经由cluster生存下来的cluster进入特殊的光栅化阶段。

在Nanite上光栅化

目前的图形硬件设想的是像素着色率,肯定比triangle高,所以普通的硬件光栅化处理器在处理非常小的表面时,光栅化效率很低,即使是完全并行处理也只有一个时钟2x2像素的东西有很多四轴overdraw,所以我们自己选择了用computeshiangle

此处列出的结构共有64位,因此需要atomic64支持。 利用interlocked maximum实现进行伪深度排序。 所以我最好的30位存储了depth、instanceID、triangleID。 因为每个cluster有128个面,所以triangleID只有7位。 我们现在实际上可以在整个opaque的Nanite pass中,用一个draw绘制到可视化缓冲器并生成。 后续材质通道根据数量为每个材质指定一个draw,并将其输出到Gbuffer

试着以集群为单位进行计算吧。 例如,计算一下我现在这个集群覆盖了屏幕的哪个范围,然后估计一下我接下来是要在这个集群上进行软件光栅化还是硬件光栅化。 利用将浮点数设为固定点数等技术,加速了扫描线整体的光栅化的效率化。

例如我在subpixel sample的时候是256。 可以看出是因为边长为16。 子像素校正保证了8位小数的精度。 这时,我们的边界使用软格子的边界。 正好是16边长的三角面片时,可以保证整数部分需要4位的精度。 在之后的计算中最大的误差,例如通过乘法进行缩放,小数为8位,整数为4位时为4.8。

乘法之后的精度被缩放到8.16,仍然在浮点精度的范围内。 实际深度测试通过了Visibility buffer前30位的深度,利用InterlockedMax这样的原子化指令实现了光栅化。 有兴趣的人可以看看Rasterizer.ush里有Write Pixel。 事实上,由于我们同时执行软件光栅化和硬件光栅化,最终硬件光栅化也仍然使用此Write Pixel编写。

Nanite中的材质处理

使用可视化缓冲器后,实际材质过程将为每个材质绘制draw call。 这里,每个cluster都保存了32位材质信息。 这32位由两种编码方法共享,每个三角形面都有自己的材质索引,每个对象最多支持64种材质,因此必须使用6位编码。

普通的编码方法共有两种。 一个是快速路径直接编码。 此时,各cluster使用的材质在3种以下就可以了。 例如,每个都有64个材质,需要使用6位数来表示索引是第几个。 3X6=18去掉18位,还剩下14位。 因为正好每7位可以分别存储第1和第2个材质的索引的三角片数的范围

前几个面索引是第一种,剩下的范围是第二种,出现的更多的是第三种。 如果一个集群超过三种材质,我们将使用一种间接的慢路径。 前7位原本保存着第1种材质、三角片范围的7位。 我们现在padding 0剩下的19位保存着一个全局,材质范围表的Buffer Index,还有6位保存着Buffer Length,slow path

这个结构有两个8位三角面index的开始和结束,有6位( 64种)材质index,实际上这个方式也很快。 想想看。 其实我们大部分的材质、模型,即使用了64个材质很多,我切成小集群后,在128个面里你切了很多section,超过3种材质的可能性其实很低。

在此处,Material Index表格中显示不同的绘制对象。 实际顺序不同。 必须重新统一材质ID进行映射。 它还有助于合并同一材质的着色计算开销。

在处理Nanite的消息传递时,为每个material ID绘制一个屏幕四边形。 这幅画只写了一个“材质深度”。 将“材质深度”保存为24位可以表示数百万种材质。 一定足够了。 每种材质都有一个材质深度平面,使用屏幕空间中的小Tile创建instanced draw,使用深度材质的深度平面进行深度剔除,从而对各材质实际输出的Gbuffer进行无效像素剔除

那么为什么要切掉tile做instanced draw呢? 因为就算用硬件做Early Z、做rejection,也还是需要时间的。 因此,在vs阶段,如果是某个tile中完全没有的材质,就可以进一步减少开销。 具体来说,可以在ExportGbuffer.usf上看到FullScreenVS这里的处理。

Nanite上的流式传输

处理完渲染部分后,让我们看一下流媒体。 由于时间的关系,我在这里可能得稍微简化一下。 因为资源很大,所以我们希望占用内存比较固定,类似于VT这样的概念。 但是,geometry与virtual texture相比有着特别的challenge。

我记得之前选择lod的时候说的。 最终的结果正好是让DAG有一个干净的Cut,所以如果数据还没有输入的话,这个Cut是错误的。 在cluster culling时也不能判断现有的数据信息。 只能用runtime去名为patching的实际数据指针。

因此,它保存了用于culling的所有级别信息,以便在加载每个实例时进入GPU中,仅对实际使用的geometry的详细数据进行流处理。 这样做有很多优点。 ——在看到新对象的瞬间,我们最低等级的根类的cluster还在。 不需要一级请求。

而且,由于我有整个cluster表,所以在feedback时,一帧就可以准确地知道实际使用的cluster的实际级别的数据。 整个层次的信息本身比较小,内存中的占有量相对来说不是很大。

回想以前的culling过程,我们在streaming粒度最小的时候也在cluster group级别,所以我们的streaming按照刚才说的cluster group进行配置。 因为一些切割的边界最好在cluster group的中间,所以我们有一些partial group的概念,最后向GPU提出要求。

是哪个cluster group,我会发送这个group所在的那个page。 如果我剪掉了partial的几个page,我会同时发送这些page的请求。 加载完成后,再次patch GPU。 我正好看了culling的整个算法,如果条件变成了叶节点,我就查一下刚才说的误差满足条件中还有一个并行条件——是否是叶节点。

除了真正的lod0集群是叶节点外,我现在还没有填充完patch,还没有加载的时候,内存中最高、最精细的级别是什么? 也是叶子的节点,整体概念是这样的。

Nanite中的压缩

实际上,我们在硬盘上利用了通用的压缩。 由于大多数主机硬件都具有通用压缩格式,如LZ77,这种压缩一般是基于重复字符串的索引长度编码,并利用Huffman编码方案对长字符串和高利用率字符串进行编码。

因为在频率上进行了优化,所以我们实际上可以重新调整。 例如,我们切到cluster后,各cluster的index buffer高度相似,我们的vertex在cluster的局部位移小,所以进行大量的position量化,用normal八面体编码进行vertex

实际上,我们对每个三角形使用一个bit,表示我的这个index是否在不连续的基础上重新开始计算。 另外一个bit表示重新开始计算的方向是负的还是正的。 像这样进行了顶点数据跨越culster变重的操作后,我们的磁盘上的压缩率非常高。 当然,我们正在探索进一步压缩的可能性。

Nanite的未来及其他

由于时间的关系,可以利用Nanite的其他几个feature,特别是Virtual Shadow Map,有效地通过Nanite渲染多个视图。 此外,每个投射shadow的光源——都有16k的shadowmap,用于自动选择每个texel向屏幕投射一个pixel的精度

接下来,我们来看看Nanite的未来有什么计划。 尽管我们目前只支持纯粹的刚体几何体类型(如opaque ),但最后还是使用Imposter方法绘制微小物体,如果超过90%,则场景中实际上是全静态对象。

所以现在的Nanite其实已经可以处理复杂场景的渲染了,在大多数情况下可以起到非常大的作用。 对于那些不被支持的情况,我们依然会走传统的流水线,进行整合。 当然,这远远没有达到我们的目标。 以后,我们希望支持几乎所有类型的几何体,以便场景不再具有概念,并且不再需要区分哪些对象启用了Nanite,例如植被、动画、地形、opaque、mask和半透明

随着Nanite的研究,我们希望达成核外光线跟踪等新技术。 这意味着,我们希望实现实际的ray tracing数据真正是Nanite加载的细节级别数据。 当然,离屏的数据可能仍然是proxy mesh。

另外,因为我们现在不支持曲面细分,所以想基于Nanite进行微多边形的曲面细分。

02

鲁明

UE5的另一大功能Lumen是新的全运动GI和反射系统,支持在大型高精细场景中无限反弹的漫反射GI和间接镜面反射。 跨度从几公里到几厘米,部分CVar可以设定到5厘米的精度。

美术和设计师们可以用Lumen创造更动态的场景。 例如,实时昼夜变化,打开手电筒,进行场景改变。 比如炸了天花板之后,光线从洞里进来,整个光线和场景的变化都会实时反馈。 因此,Lumen大大减少了烘焙照明的重复时间损失,不再需要处理lightmap的uv,大大提高了质量和项目重复效率。

为了提供不同尺度的高质量GI,Lumen将在不同的平台上应用不同的技术组合。 但是,现在Lumen有很多功能不足得到了改善。 首先,让我们简单地看一下Lumen的大框架。 为了支持有效的跟踪,除了支持RTX硬件的ray tracing外,还在其他情况下使用Lumen在GPU上维护完整、简单的场景结构。 这叫做Lumen scene。

其中的一些信息是通过脱机mesh烘焙生成的,包括mesh SDF和mesh card。 这里的card只标记了这个mesh用网格隔开后,从哪个位置拍摄其方向和Bounding Box的标记。

使用这些辅助信息高效地光栅化Nanite的多视图,以生成Gbuffer及其后续所需的其他数据,并在运行时在两个级别上更新LumenScene。 一个是在CPU上有新的实例进入,或者控制几个综合流的计算。 另一个是更新的GPU数据和更新的LumenScene注入,Diffuse光直接和间接照射到灯光缓存。

我们根据现在的屏幕空间放置一些Radiance Probe,使用比较特殊的手段进行重要度的采样。 通过高效的Trace Probe获得Probe内的照明信息,对Probe的照明信息进行编码,生成Irradiance Cache并制作spatial filter。

当然,之后还有一些fallback到global世界空间,最后Final Gather回来与全屏bentnormal合成生成,最终照射全屏间接光,再在上面进行temporal滤波这就是我们的Diffuse全屏的光,最后结合Direct的光,得到了最终的渲染结果。

Lumen中的跟踪

Lumen的整体框架是软件跟踪,通过Mesh SDF进行快速的Ray Tracing。 在硬件允许的情况下,我们使用RTX。 这个今天不谈。 Lumen的跟踪是Hybrid的方案,也包括优先利用HZB制作画面空间的跟踪。 如果失败了,我会在近距离全屏制作Mesh SDF的Trace。 因为这里用Mesh SDF的instance扫描其实效率还很低。

通过bvh访问GPU时,树结构缓存的一致性差,只需在1.8米以内创建一级加速结构。 此时,使用简单的Froxel进行网格分割,快速求出所有实例的Bounding Sphere和对应cell的交叉结果,并存在于对应cell的列表中。 这在全屏中一次完成

下一次跟踪时,我每次只需访问当前的跟踪点,例如marching以后的位置,所在的小区就可以立即计算出来。 然后直接查里面的instance列表,查第二层加速结构的实际东西和列表instance的SDF,做一次marching拿走

在更远的地方,合并场景以创建生成全局的SDF。 这是剪辑地图。 但是提高精度的话,数据存储等各个方面每增加一倍,精度就会增加八倍,所以我们有一些稀疏的表现。 稍后简单地说。

如果trace无法到达,请循环浏览全局SDF剪辑地图,然后对每个级别的剪辑地图进行loop,直到全局SDF。 例如,如果200米以上都没有到达trace,那就是miss。 当然,我们在之前的Demo中也使用RSM做了最后的fallback,但是现在这个版本还没有放进去。

生成SDF时,“tracing”会执行保守操作以防止薄壁穿透。 SDF其实是volumetric,在以voxel间隔采样的生成过程中,如果我面薄,在你的voxel精度以内,其实我们有一些保守的处理。

Lumen和场景结构

随之,我们trace到达某个表面后,无法在SDF中获得我们实际需要的数据,只能帮助我们快速找到交点的位置。 这个时候,我们能得到什么? 近场MeshSDF的时候MeshId我知道。 因为遍历列表时保存了; 此外,因为您也知道SDF,所以可以在SDF的梯度中计算出相应的正规,但有ID、正规和位置。 我怎么得到Radiance? 也包括Gbuffer的数据。 此时,需要高效的参数化方法,因为没有用于插值计算的三角化数据,也没有各种材质的特性。

使用了瓷砖型的CubeMapTree结构。 首先,我们描述了在导入Mesh时进行预处理以生成一组Card。 如果为runtime,则根据Mesh的Card信息,使用Nanite对放置在贴图中的每个实例进行有效光栅化,并生成相应的Gbuffer。

Atlas虽然在大的Atlas中,但实际上几张里面存放着MRT,——存放着包含albedo、opacity、normal、depth这样的信息的3张。 将这个Atlas保存并称为Surface Cache,其实是大家最终看到的LumenScene。 当然,LumenScene经过SDF tracing,进行tri-planar re项目。 这是我们追踪的结果。

要说我们在tracing的时候要跟踪到哪个位置,就是找到它对应三个方向的Lumen card,对光栅化的这些信息进行tri-planar reproject,以获得这一点所需的信息。 包括Gbuffer、Radiance信息。

Radiance信息来自哪里? 生成card时,直接注入光线,以生成其Irradiance的Atlas。 然后,该Atlas根据维护的budget更新对应的card,从texel利用GlobalSDF进入trace的前一帧的lighting状态,即前一帧的lumensccing状态

所以,当我们通过屏幕空间Probe去trace时,trace到达的Irradiance cache中的东西是多次反弹的结果。 card在这个Atlas中存储的cache,其实都是2的整数次方,为了方便做mip。 因为我们有使用prefilter的mip,利用conetracing快速进行prefiltering结果的tracing的阶段。 至于更远的Ray,我们其实在trace的时候,已经租了GlobalSDF,超过1.8米的时候,这个时候我们也没有对应的MeshID。

同样,如果对应于生成GlobalSDF的clipmap,则可以使用Surface Cache生成voxel Lighting Cache或LumenScene的更低精度的voxel表示形式。 该voxel Scene是在对Cube Map Tree进行预处理后,由radiance合并而生成的。

此时,我们针对每一帧重新生成voxel Lighting Cache。 Lumen整体的结构持续存在于GPU上,在CPU上维持其增减。 我们是什么样的新进入Streaming的,视角调整后能看到哪个card,为了抑制开销,我每帧固定更新一定数量的card,根据对应的Lighting类型对于在跟踪时未显示在屏幕上的材质球遮罩,将在Global SDF Trace中执行。

文件网关

有跟踪的手段,从那里得到想要的数据的信息后,解决最终的GI问题。 在传统的模型中,例如Cards中保存着Surface Cache,虽然已经有多次反弹的照度信息,但是这里将追踪到的解决表面缓存不一致的计算分离为Card Capture和Card光照计算部分,直接在屏幕空间中

在传统的RTX GI中,1-2spp大多只能支撑Gbuffer发出的均匀分布在BentNormal半球空间的光。 在SpatialTemporay中,通过色散引入的该滤波在光相对充分的情况下非常有效,但在光不充分的情况下,例如只有一束光从门的间隙或小窗进入的情况下,在稍远的地方的你的traray 实际上有光源的地方概率太低,过滤前的画面信息太少,最终过滤后的质量也非常差,无法接受。

我们的方法利用的是Screen Space的Probe,远远低于Gbuffer分辨率。 如果基于实际像素插值失败,大约每16个像素,请将其进一步细分并放入一个Atlas中。 我的每个Probe实际上有88个Atlas,投影着小的8面体的是半球。 自己的World Space normal半球均匀分布着我的立体角朝向的那个Tracing的方向。 在每一帧中对这个采样点也进行一些jitter,稍后进行插值。

我们也在像素平面上,根据BRDF的重要度对最后全屏的每个像素进行采样,让周围的Screen的Probe进行与我的方向一致的权重调整,然后进行插值。 然后,在计算Probe时,利用半球扔向八面体的方式,将88的像素全部集中到Atlas中,在细分时放在下面。

所以最坏的情况是例如各像素是一个前景,下一个像素是一个背景场景——。 这实际上是不可能的,但却是极端的情况。 在这种情况下,我将为Probe Cache细分每个像素,并对每个像素进行该跟踪。 为了避免这种情况,我们其实粗暴地限制了整个Atlas的大小,也就是最细分的东西。 如果我填不进去,请不要。

这样的优点是,我以1/16的精度执行的Screen Probe实际上是1/256,即使88的我处理的像素是以前的1/4或1/8,当对Spatial Filter的最后一个像素执行插值时,仍然是当求解间接环境光蒙特卡罗积分时,reproject所返回的Incoming Radiance值可以用于引导灯光输入采样。

同样,BRDF也可以这样做。 例如,BRDF值小于0的部分与入射光无关,对出射没有贡献,随意地在该方向上lighting成为前一帧的incoming radiance。 在这一点上有多少光朝这个方向来了,我的贡献也是0——因为我不需要它,我最终会把这两个东西放在一起,作为我新的这个框架的probe的importance sampling的方向。

最后,我根据这个方向去跟踪。 然后,radiance存储在与之对应的另一个88图,Atlas中。 小而亮的部分越远离表面,每个帧都会有jitter或有方向,引导方向不同。 由于可能无法跟踪,噪波越多,且跟踪长度越长,光线的完整性越差,因此较远的光源的光线变化频率也相对较低。 因为我离得很远之后局部的光有点偏移,所以对我这里的影响很小。

所以,我们可以用一个世界空间的probe来处理。 因为这个时候可以制作大量的cache。 在这里,我的世界空间也是clipmap,那也是稀疏存储。 因为只有我的Screen Space的Probe Tracing无法访问的东西,才会配置更多的World Space的Probe进行更新处理。 这里就不往下说了。

最终,需要以全分辨率进行积分。 在这种情况下,可以通过全分辨率像素获得BRDF采样。 那个方法,正如我刚才说的,是从Screen Probe上找。 例如,88像素周围的东西会寻找和那个方向一致的weight进行插值,但即使这样噪声还是很多,所以我们实际上要从那个mip中进行预处理,从通过过滤器获得的结果开始寻找。

另外,因为自己面对的平面,例如88像素周围的东西寻找与那个方向一致的weight进行插值,所以最终将八面体的radiance变换为三次球谐,在全分辨率时能够非常高效地利用球谐系数进行漫反射积分,结果是能够实现漫反射积分

最后再试一次吧。 我把每个像素做完后,再做一次temporal的过滤。 但是,像素跟踪的位置的速度和深度决定了我的像素的变化。 是否快速移动并投影了物体的区域,决定了我的temporal filter的强度。

我的temporal filter越弱,其实相当于之前我去采样的时候积分的时候,我采样的周围33 Spatial Filter的效果越强。 总体上Lumen的框架是这样的,我跳过了很多细节和一些特别处理的部分。 例如,虽然没有提到半透明物体的GI,也没有特别提到“Spectular”,但如果粗糙度为0.3到1,如“Spectular”,则实际上与此处的importance sampling的diffuse一致。

Lumen的未来

期待将来镜面反射等的进一步改善。 Glossy反射现在可以很好地处理,但镜面反射可以更好地处理SkeletalMesh的场景表示方式、破碎物体的场景表示方式和整个非模块化物体,而无需硬件跟踪。 因为目前整个模块化的captured card或SDF的各种精度处理可能还不够。

我们希望提高植被质量,更快地支持光照变化。 因为有很多hard limiter的更新,比如card的数量,所以更新太快了,跟不上。 最后,我们希望支持更大的世界,例如SDF数据流和GPU driven的表面缓存。 关于Lumen,今天就说到这里。

03

其他功能和QA

描述了两大招牌功能后,让我们快速看看其他功能。 例如,在最经常提到的大世界里得到了支持。 UE5以后,我们有了更好的工具。 例如,World Partition升级到了全新的数据组织方式。 结合流系统,我们不需要手动处理运行时流。 引擎会让你自动隔离不同的Partition,自动处理加载策略。

另外,基于此,有数据层对不同逻辑的处理,世界分区流策略基于层定制不同的策略,级别实例——对级别进行操作

为了进行协作,还引入了One File Per Actor。 每次大家在地图上编辑或添加时,实际上都会更改为与独立的加速器相对应的文件。 文件锁定的粒度很小,所以不会移动整个地图文件。 这样,引擎也会自动管理这些零散文件的changelist生成。

最后,我们进行了大世界的精度支持,将整个Transform的各种计算改为双精度浮点支持。 与Turnkey的新软件包工作流一样,移动端延迟呈现也进入了测试阶段。

iOS还进行了许多其他改进,正式发行版添加了对opengles延迟渲染管线的支持,例如mali像素局部存储。 它还加入了新的shading model,包括DFShadow支持,以及与pc集成并由Burley SSS参数驱动的移动预集成外观。

同时,我们终于支持了DXC中的半精度,用DXC变换了所有的Metal Vulkan openGLES。 此外,我们还添加了点光源材质球、CSM cache和565个优化带宽的RVT,以创建新的GPU实例调用和更高效的自动实例调用等功能。

QA

问: Q:UE5.0正式版什么时候发布?

王祢:预定明年上半年,可能会在4月左右发表。

问: Q:UE5.0以后也支持曲面细分吗?

王祢:从很多硬件平台的曲面细分效率问题来看,我们打算彻底清除。 未来我会在Nanite上试试,但还没做到。 所以现在的workaround如果不变形的话,只能用Nanitemesh或者Virtual Heightfield Mesh来处理。

( TGDC 2021将于11月22日-24日进行直播,感兴趣的读者可以点击下面的小程序观看。 )游戏葡萄招聘产业记者/内容编辑,点击“阅读原文”了解详情

上海人才战|广深人才战|元神地图设计

英雄联盟手游|暴雪到天美|哈利波特美术

崩溃新作|黑暗迷宫2|盗版横行

悲伤的二字ID

很多伙伴都在问关于悲伤的二字ID的问题。 今天,本站编辑给大家整理了所有关于悲伤二字ID的问题。 我希望能帮到 […] 【查看详情

非常悲伤的网名

很多伙伴都在问关于非常悲伤的网名的问题。 今天,本网站的编辑整理了所有关于非常悲伤的网名的问题。 我希望能帮到 […] 【查看详情

爱情游戏ID

很多小伙伴都问了关于深度游戏ID的问题,今天本站编辑给大家整理了所有关于深度游戏ID的问题。 我希望能帮到你。 […] 【查看详情

版权声明: 本站内容部分来源网络,版权归作者所有,如有侵权,请联系我们删除!
相关文章
悲伤的二字ID 技巧
很多伙伴都在问关于悲伤的二字ID的问题。 今天,本站编辑给大家整理了所有关于悲伤二字ID的问题。 我希望能帮到你。 有哪些2个字的好听的伤感网名? 1、浅港、琉箫、残月、绝交、孤冷、离欢、心塞、泪痕、守梦、逝啸、破屐、踏尘、浅哀、蜡烛伤、冷眸、浅沫、桀、桀、堕落、痛烈、舞魅、化吻 2、天绚、忧泣、恋夜、殡情、靖季、间隙洞、蓝郁、葬爱、梦殇、搁浅、凉城、断桥、荒城、西村、青屿、磉愁、抹绿、晨曦、寺瑾…
管理 2022-12-06 17:50:47
非常悲伤的网名 技巧
很多伙伴都在问关于非常悲伤的网名的问题。 今天,本网站的编辑整理了所有关于非常悲伤的网名的问题。 我希望能帮到你。 特别伤感网名 特别悲伤的网名如下。 1、蓝鲸忘记了大海 2、从此不再等你 3、曲子没结束的人散了 4、我们在一起了 5、乘我之病取我性命 6、孤独的人 7、独自流泪 8、老半天了 9、孤独的电影院 10、是我的解毒剂 11、莪想关心和怕多余 12、太爱了受伤了 13、自大生存 14、…
管理 2022-12-06 17:50:46
爱情游戏ID 技巧
很多小伙伴都问了关于深度游戏ID的问题,今天本站编辑给大家整理了所有关于深度游戏ID的问题。 我希望能帮到你。 好听有含义的游戏名字 有深意的游戏id 1、温柔地藏在心里 2、7秒的重量 3、感叹浮沉 4、良人归佳人不独醉 5、浪冢 6、像野狗。 7、自闭症患者 8、沙坑醉卧 9、山风 10、为害苍生 11、迟到的心 12、骚货永远疯了 13、你从月亮里来 14、陌生的花 15、无法取得联系 16…
管理 2022-12-06 17:50:45
具有深远意义的id名王者 技巧
很多小伙伴都在问一些有深意的关于id名王者的问题,今天,本网站的编辑整理了所有有深意的关于id名王者的问题。 我希望能帮到你。 王者荣耀有诗意的id有哪些? 推荐几对古风情侣的网名: 男“温暖的橘”女“凉柚” 男人“语言风华”女人“对想法莞尔” 男【一木一孤生】女【一花一沉沦】 男人“一杯旧酒”女人“黄昏独自愁” 男人“安心抽丝”的女人“余生吟清歌” 男:“从来没有像上帝一样来过”的女:“从来没有…
管理 2022-12-06 17:50:44
2022最新游戏情侣名字 技巧
很多伙伴都在问关于2022最新游戏情侣名字的问题。 今天,本网站编辑整理了所有关于2022最新游戏情侣名字的问题。 我希望能帮到你。 2022最潮吃鸡情侣网名 现在的小情侣为了培养共同的话题,自然会培养同样的兴趣。 很多小情侣以游戏为切入点。 目前最热门的“吃鸡”游戏,成了不少小情侣撒狗粮的好“据点”。 如果你想给“吃鸡”游戏取最受欢迎的恩爱情侣的名字,就看看这些名字吧。 2022最潮吃鸡情侣网名…
管理 2022-12-06 17:50:42
2022足球世界排名 技巧
很多小伙伴都在问关于2022足球世界排名的问题,今天本站编辑整理了所有关于2022足球世界排名的问题。 我希望能帮到你。 足球国家队世界排名2022 2022年足球国家队世界排名: 1、巴西,英文名: Brazil,总要点: 1832.69。 2、比利时,英文名: Belgium,总要点: 1827。 3、法国,英文名: France,总要点: 1789.85。 4、阿根廷,英文名: Argent…
管理 2022-12-06 17:50:40
又短又棒的游戏昵称 技巧
很多伙伴都在问关于又短又漂亮的游戏昵称的问题。 今天,本站编辑给大家整理了所有关于短而漂亮的游戏昵称的问题。 我希望能帮到你。 游戏昵称大全简短好听,取个游戏昵称好听 游戏昵称大全短听500个 1 .那时青涩 2 .损伤菊花 3 .魔尊杀神 4 .我爱你像老一样 5 .今夏37 6 .与行星的交往 7 .雨碎江南 8 .冷漠的心 9 .恋人与鲜花 10 .可爱的女孩 11 .顾生晓梦 12 .安于…
管理 2022-12-06 17:50:39
游戏男人的名字很漂亮很帅 技巧
很多小伙伴都在问关于游戏男人名字好、帅的问题,今天,本站编辑给大家总结了一个关于游戏男人名字好、帅的问题。 我希望能帮到你。 游戏名字好听又霸气男 适合男生的游戏名 1、一统天下 2、请给我水 3、殇子狼魂 4、人贱无药可救 5、乱战情魔 6、清晰风云 7、等我王带你疯了 8、精武斗国 9、至尊元芳 10、一手遮天 11、碎冰块 12、懒散的衬衫小 13、至尊狂魔 14、霸者才是王道 15、帅到没…
管理 2022-12-06 17:50:38
2020最受欢迎游戏的名字 技巧
很多伙伴都在问关于2020年最受欢迎的游戏的名字的问题。 今天,本站编辑整理了所有关于2020年最受欢迎游戏名称的问题。 我希望能帮到你。 2020最火的游戏名字 霸气独特网名 1、痞子配酒 2、一生孤单 3、未知的疯狂 4、无名老师 5、嫔颜@ 6、爱玩之徒 7、假的。 -天使 8、心动不动 9、任性青春 10、为你喝酒 11、从你身边逃跑。 12、给硪香烟 13、魅罗红颜乱 14 ( )烂桃花…
管理 2022-12-06 17:50:36
甜美有玩心的游戏名字女孩 技巧
很多朋友都问了我一个关于一个名字叫甜甜游戏的女人的问题。 今天,本网站的编辑整理了所有关于一个叫甜甜游戏名字的女性的问题。 我希望能帮到你。 女生撩人的游戏名有什么? 【01】,不需要那样的爱 【02】、轻吟浅唱 【03】,在奈何桥面前无可奈何 【04】、放烟花的男孩 【05】、一又二分之一的夏天。 【06】、花开花落回忆岁月 【07】、雪馨沁梦 【08】、)文艺骚货 【09】,女衬衫的故人 【1…
管理 2022-12-06 17:50:34