虚幻引擎4.22的网格体绘制管道转换指南

包括虚幻引擎4适用参考和指南在内的产品文档

Windows
MacOS
Linux

在虚幻引擎(UE4)4.22版本中,网格体绘制管道 会被完全重写。主要的变更是从 即时(Immediate) 模式(每一帧都构建可见的绘制)转移到 保留(Retained) 模式(所有场景绘制都提前准备好)。这是一个重要的变更,因为它能够支持新兴技术,例如DirectX光线追踪(DXR)技术,该技术要求着色器绑定表用于整个场景,或者GPU驱动渲染技术,在该技术中CPU必须能够在不知道可视性的情况下准备绘制。

有关UE4 4.22中网格体绘制管道变更的更多详情,请参阅网格体绘制管道 文档和游戏开发者大会(GDC)报告重构虚幻引擎4.22的网格体绘制管道

网格体绘制命令

在旧管道中,网格体通道绘制规则基于"FMeshBatch"直接执行渲染硬件接口(RHI)命令。新管道引入了网格体绘制命令"FMeshDrawCommand"的概念,将其作为"FMeshBatch"与RHI之间的接口。网格体绘制命令是一个完整的独立绘制描述。它存储RHI需要知道的有关绘制的所有信息。这允许缓存和重用整个绘制状态及其着色器绑定。

静态绘制列表和基元集

在4.22的网格体渲染管道中,静态绘制列表("TStaticMeshDrawList")和基元集(例如"FTranslucentPrimSet"和"FCustomDepthPrimSet")被替换为"FParallelMeshDrawCommandPass"。"FParallelMeshDrawCommandPass"每个通道封装一个可见的网格体绘制命令列表。

新设计有两个重要的变更: 

  • 首先,每个场景的网格体列表 被替换为 可见网格体列表。之前绘制静态网格体通道时,会遍历场景中每个静态网格体的整个列表("TStaticMeshDrawList"),通过为每个静态网格体选中"FViewInfo::StaticMeshVisibilityMap"来选择可见的网格体。在新设计中,绘制只是一个可视化网格体绘制命令数组的简单遍历(FMeshDrawCommandPassSetupTaskContext::MeshDrawCommands)。随着场景复杂度的增加,新方法可以更好地扩展。 

  • 其次,一个重要的变更是我们合并静态和动态网格体绘制列表的方式,这简化了整个网格体绘制管道,也使渲染器能够将静态和动态绘制排序在一起。

该管道还通过"DrawDynamicMeshPass"函数提供即时模式网格体渲染模拟。这是一个非常灵活的渲染路径,但应该只用于非性能关键型的网格体通道,因为它不支持缓存、自动实例化和进行多个动态内存分配。例如,它替换了"DrawViewElements",后者负责渲染纯编辑器的助手网格体。

绘制规则

"FDepthDrawingPolicy"或"FBasePassDrawingPolicy"等绘制规则被替换为"FDepthPassMeshProcessor"和"FBasePassMeshProcessor"。特定的通道网格体处理器派生自一个"FMeshProcessor"基类,负责将每个"FMeshBatch"转换为一组用于通道的网格体绘制命令。这是最终的绘制过滤发生的地方,选择着色器置换并收集着色器绑定。

着色器绑定

之前,所有的着色器参数都是依据相关绘制规则直接在"RHICmdList"上设置的。现在,所有参数都被收集到"FMeshDrawSingleShaderBindings"中,稍后在绘制过程中通过调用"SetOnCommandList"在"RHICmdList"上设置这些参数。这需要能够使用着色器绑定缓存完整的绘制状态。

旧管道使用"FDrawingPolicyRenderState"来传递通用的高级网格体通道渲染状态,例如通道统一缓冲区。新管道将"FDrawingPolicyRenderState"重命名为"FMeshPassProcessorRenderState",而没有对其功能进行重大变更。

着色器绑定的其他部分填充在着色器的"SetParameters"和"SetMesh"函数中,这些函数被替换为"GetShaderBindings"和"GetElementShaderBindings",且pass per-draw参数位于自定义的"ShaderElementDataType"中。

通过重构,许多松散的参数被提取到每个通道或其他的统一缓冲区中。这是设置参数的首选方法,使用松散的参数将禁用自动实例化,而且会导致每次绘制之间持续更新缓冲区,从而导致速度减慢。

之前,标准统一缓冲区,例如"ViewUniformBuffer"或"DepthPassUniformBuffer"都是使用新数据在每一帧中重新创建的。在新管道中,它们是永久性、全局性的(保存在"FScene::FPersistentUniformBuffers"),而不是重新创建它们,它们将新数据传递到"RHIUpdateUniformBuffer"中,它们的内容使用新的RHI函数进行更新。这种间接性使着色器能够接收每帧的数据,尽管会缓存它们的网格体绘制命令。

FPrimitiveViewRelevance

"FPrimitiveViewRelevance"扩展了两个额外的相关性标记:

  • 单独的速度传递需要 bVelocityRelevance

  • 半透明自身阴影需要 bTranslucentSelfShadow

此外,所有动态绘制现在都依赖于视图相关性,禁用视图相关性中的某些传递也将禁用其渲染。

着色器

新管道引入了GPUScene,它是一个结构化的缓冲区,包含场景中所有基元的基元统一缓冲区数据。目前,只有本地顶点factory(静态网格体组件)和SM5功能级别可以使用该渲染路径。着色器需要使用"GetPrimitiveData(PrimitiveId)",而不是直接访问基元统一缓冲区,来在启用GPUScene的情况下进行编译。

基元数据访问通常在 Custom Expression Material 节点内使用。例如,用于访问基元的边界框。为了转换这些,"Primitive.Member"需要替换为"GetPrimitiveData(Parameters.PrimitiveId).Member"。

Tags
Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback