【UE4 渲染管线系列1】鸟瞰UE4渲染管线

本系列所有文章只为了搞清楚一件事:UE为了渲染一帧画面都做了什么。本系列计划由上至下地逐步了解UE4渲染管线,并明晰渲染的每个环节要做什么,基于什么原理,进一步地,有哪些关键的代码负责这些部分。在本篇中,我们将站在最高处,俯瞰UE4的整个渲染管线,来了解其组成部分。

来一张卫星地图

这是UE官方教程(渲染部分)的一张导图,主线节点将整个渲染过程划分为了数个阶段,而各个框体又标明了每个阶段所做的数项工作。(注:现在官方教程中只有UE5的渲染管线图,其中主要的区别在Nanite和Lumen的加入,以及动态光照部分的Virtual Shadow Maps等,整体变化并不大)

画面之外——CPU帧

逻辑处理帧

在两帧之间,可能会发生一些影响画面的事,例如角色的视角转动,场景中物体的移动,Actor之间的相互作用,转场等逻辑。这些逻辑是由CPU处理的。这些逻辑发生之后,才能开始准备这一帧的渲染。CPU处理游戏逻辑对场景的影响的行为被称为CPU Frame 0

CPU Frame 0

从上图可以看到,为了提高效率,CPU与GPU是并行工作的。在GPU渲染Frame A的时候,CPU已经在处理Frame B和C了。

可见性与遮挡处理

除了逻辑,剔除也是由CPU完成的。UE4有许多种剔除方式,用于去除不应该出现在画面中的物体。

Distance Culling 距离剔除

距离剔除是一种简单粗暴的,直接根据物体距离相机的距离进行剔除的方式。例如剔除大世界场景中超远距离的石头和树等。通过设置物体的绘制距离的方式可以非常便捷地设置某些物体是否显示。此外,还可以使用剔除距离体积(Cull Distance Volume)来覆盖某一范围内的物体的绘制距离值。对于一些具有精细室内结构的大型室外场景,距离剔除可以剔除一些在室外看起来小到不重要的室内结构,从而优化室外的渲染速度。

Frustum Culling 视锥剔除

视锥剔除用于剔除相机视野外的物体。在UE5中使用freezerendering指令可以很容易地看到视锥剔除的效果:

渲染暂停后,转动视角即可看到视锥外的物体大都没有渲染,只有部分物体(石头)因为与视锥内的石头被一同批处理而渲染出来。

Visibility Culling 可见性剔除

顾名思义,可见性剔除被用于剔除位于视锥内但是被其他物体所遮挡的物体。有些GPU具有遮挡查询功能,可以从硬件层面查询遮挡信息,从而高效处理一些动态的精细的遮挡。而对于较为低端的机器,也有软件的方式来计算遮挡,如使用层次包围盒(BVH)或是潜在可见集(PVS)来加速计算。在不同的距离,为了节省资源,物体的形状和细节可能被简化,因此网格层次细节(Mesh LOD)也参与到遮挡剔除中。

Precomputed Visibility 预计算的可见性

有时候玩家的视角并不是自由的,他们的行动路径可能是十分受限的,这使得开发者可以通过预设的方式决定哪些物体会被看到。所谓预设就是将空间划分为一系列单元(Cell),预设好在每个单元中可以看到的物体,就可以在运行时迅速确定哪些物体要被剔除。

正片开始——GPU帧

GPU善于并行处理逐像素的信息。GPU帧的渲染阶段可以大致分为创建几何缓冲区(G-Buffer),处理光照、阴影,处理额外内容(体积雾等),添加后处理等步骤。


什么是一个Pass?

在接下来的内容中,Pass这个词会被频繁提到。字面意义上理解,一个Pass就是“一套流程(通道)”,通过一个特定的Pass可以加工出特定的东西。

通常一个Pass主要包含了一系列drawcall,这些drawcall运行在GPU上,可以用来以某种材质渲染某些mesh(网格体)。一个drawcall就是一条由CPU向GPU发出的指令,要求GPU“使用当前绑定的资源(材质、着色器等)绘制这个mesh”。drawcall是最小的渲染单元,每个drawcall都是一个mesh和一个材质的组合,如果有两个物体长得一模一样(有相同的mesh和材质),则可以通过合批(batching)合并为一次drawcall(像是上面视锥剔除部分提到的石头)。一个mesh包括这个网格体的顶点缓冲(每个顶点的属性,可能包括位置,法线,UV等)、索引缓冲(每个三角形是哪几个顶点连起来得到的);一个材质包括它使用的着色器程序、纹理引用(比如法线贴图)、材质的属性(包括但不限于颜色、金属度、粗糙度等)。每个drawcall还包含一些设置,例如渲染时是否开启深度测试、模板测试规则等。每个Pass可能只负责部分的drawcall,而且Pass是有先后顺序的,因为有些Pass的进行可能依赖于前面Pass的输出。

Pass的结果将会输出到帧缓冲(Frame Buffer)或者中间纹理(Intermediate Texture)中。


Early Z Pass 提前深度测试

CPU帧的可见性剔除省去了完全被遮挡的物体,剩下的物体可能仍然有遮挡关系。如果直接按照由远及近的顺序绘制,可能会导致部分像素被反复覆盖多次,浪费了计算时间。因此默认情况下会采用一个提前的Z Pass来产生一张深度图,计算每个像素能够直接看到的最浅深度。这张图中的深度信息将会在后面的许多部分中使用到。

Base Pass 基础通道

Base Pass是延迟渲染(Deferred Rendering)架构中的核心阶段,负责将物体表面的材质属性(如颜色、法线、粗糙度等)写入G-Buffer​(几何缓冲区),为后续光照计算和后期处理提供数据基础。它是渲染流程中最关键的一步,直接影响最终画面的质量和性能。

Base Pass的内容

在延迟渲染中,Base Pass的核心就是填充G-Buffer。具体来讲,Base Pass负责:

  • 把不透明的或遮罩材质的属性渲染并输出到G-Buffer
  • 读取静态光影并保存到G-Buffer
  • 应用DBuffer中的贴花
  • 应用雾

在前向渲染中,Base Pass需要直接计算光照并输出最终颜色而不是G-Buffer,此处暂且省略。

静态光影

静态光影顾名思义,就是不会发生变化的光照效果。例如在某些固定布景中的光照信息。通过预计算,直接将光照和阴影信息烘焙(baking)光照贴图(lightmap)、顶点数据或光照探针(Probes)中。这种做法可以通过离线预计算方式保存高质量的光照信息,以便在运行时节省运算量并提高质量。但是为了保存光照贴图,可能会消耗大量的显存。UE中的Lightmass就是用于计算静态全局光照的离线烘焙系统,可以计算复杂的光线反射和间接光照效果并储存到lightmap或是light cache中。

G-Buffer

G-Buffer即Geometry Buffer(几何缓冲区),里面存储了一系列的全屏图片,例如当前屏幕空间中每个像素的深度信息、法线信息、粗糙度、金属度等各种信息。从示意图中可以看到,如果将这些图片提取出来,颜色会很奇怪,这是因为颜色(RGBA)在这里仅仅作为存储数据的空间。例如,Buffer A中的每个像素,其RGB通道被用来存储这个点的法线XYZ,而A通道被用于存储这个点的粗糙度R,其他每个buffer也以类似的方式存储信息。这些信息在其他Pass中可能会被多次使用。

动态光影

大部分在UE中渲染的光照都是动态光照。UE提供了一些高级功能用于优化直接以及间接动态光照的表现。

直接光照

对于直接光照,UE允许光源绑定到IES profile文件,这种文件描述了真实灯具的光强分布,将其导入引擎可以让虚拟光源的效果更贴近真实的光照。此外还可以定义一种被称为Light Function的材质函数,来动态控制光源的颜色、亮度、形状等,从而实现诸如动态投影(比如树叶的阴影)、体积光等效果。此外,UE还有一些特殊的阴影:

技术内容
Inset Shadow通过法线贴图等方式在物体表面产生阴影
Contact Shadow两个物体接触表面之间的细微阴影,可以缓解漂浮感
Per Object Shadow为指定的物体分配独立的阴影贴图,提高精度(消耗大)
Cascaded Shadow Map根据距离调整阴影分辨率

间接光照

间接光照主要是通过光线追踪,实现全局光照、环境光遮蔽等效果。

反射

这一部分列出了UE中使用的许多实现反射的技术。除了光线追踪以外,还提到了屏幕空间反射(SSR),这是一种完全实时的反射处理方式,而且仅会反射屏幕内的物体(例如在水中站立的角色)。它只使用当前帧的颜色和深度缓冲(它们在G-Buffer里),并可以在无需预计算的条件下得到高精度的反射效果。

后处理

后处理的特点是只会使用现有的缓冲区,因此它们都是针对当前这一帧被看到的内容做的处理。后处理可以被分为两部分,分别是模拟真实相机的视觉效果(例如景深,泛光等)和制造一些幻象(利用屏幕空间全局光照、次表面散射等技术)。后处理效果是施加在相机上的,可以通过在场景中放置后处理体积来对进入其中的相机施加后处理效果。

总结

以上是对UE4渲染管线的简要概括与梳理,省去了一些附加内容和调试方面的内容。后续文章可能会针对其中的某些具体技术,研究其原理、例子和代码实现,以及在代码层面研究UE是如何构建渲染模块的。

Begin Play | Rendering | Epic Developer Community

Unreal’s Rendering Passes – Unreal Art Optimization

UE4渲染管线笔记(一) – 知乎

UE4渲染管线笔记(二) – 知乎

虚幻引擎渲染学习笔记:从入门到实践-CSDN博客

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇