本文内容
编写通道
Passes 确定帧的渲染方式。您可以通过集成不同的通道(例如光照或后期处理通道)来自定义渲染管道。传递是从 PassTemplates 实例化的,可以用 JSON 或 C++ 创作。如果要自定义通道模板的功能,可以在 C++ 中定义自定义的 Pass
类。
有关创作 PassTemplate 的信息,请阅读下面的 编写 PassTemplates 部分。
Root Pass 和 Pass Registry
在开始创作通行证之前,请务必了解通行证系统(请阅读 Pass System 部分)。在创作通行证时,了解以下要点也很重要:
- 通道的结构是嵌套通道树,从 根通道 开始。
- PassTemplate 必须在 Pass Registry 中注册才能使用它们。
根通道
通道系统的基础是 根通道,它开始嵌套子通道的树。每个过程都在其父过程中注册,以建立过程的整体上下文。通道可以是渲染通道,也可以是具有嵌套子通道的子根。
其中一个关键通道是MainPipeline.pass
,它是定义管道渲染逻辑的父通道。您可以在资源文件 MainRenderPipeline.azasset
中更改 Atom 的默认管道传递。
Pass 注册表
pass 注册表 包含所有可能的 pass 模板的注册表。要使用通行证模板,必须将其包含在通行证注册表中。请注意,pass 注册表可以包含从未使用过的 pass 模板。您可以通过Name
和Path
属性包含通道模板的名称和.pass
文件的路径,将通道模板添加到通道注册表文件PassTemplates.azasset
中。
以下示例显示了 pass 注册表的代码片段。您可以通过在AssetPaths
中添加另一个元素来添加新通道。
// PassTemplates.azasset
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "AssetAliasesSourceData",
"ClassData": {
"AssetPaths": [
{
"Name": "DepthPassTemplate",
"Path": "Passes/Depth.pass"
},
...
{
"Name": "ForwardPassTemplate",
"Path": "Passes/Forward.pass"
}
...
]
}
}
构造 Pass Tree
每个父传递都包含一个按上下文顺序排列的直接子传递列表。从根通道开始,将列出子通道的第一级。相同的规则适用于每个 sub-root pass,最终构建 pass tree。
创作 PassTemplate
一个 PassTemplate(参见 PassTemplate.h
)用于实例化一个 Pass(参见 ‘Pass.h’)。它指定 Pass 以及该 Pass 拥有的任何 PassAttachments(PassAttachment.h
)的输入和输出。它可以在代码中作为 C++ 创作,也可以在数据中作为 JSON 文件(扩展名为 .pass)进行创作。
当 PassTemplate 创作为数据 (.pass
) 时,它们将序列化为 PassAsset。PassAsset(参见PassAsset.h
)是资源系统用于序列化的 PassTemplate 的精简包装器。
PassTemplate 的组件
PassTemplate 的组件根据其Pass
类而有所不同。Pass
类由 .pass
文件中的PassClass
属性指定。
PassTemplates 指定输入和输出,并通过组件Slots
, Connections
, Image Attachments
, 和 PassData
定义其功能。
PassTemplates 还可以包含一个 PassRequests
容器,该容器列出了子传递。当 PassTemplate 实例化为 Pass 时,每个 PassRequest 都会创建一个子 Pass。
PassTemplate JSON 文件(*.pass
) 的完整分类可以在
PassTemplate文件规格 部分找到。
注册 Pass 模板
在实例化 PassTemplate 之前,必须将其注册到 PassSystem。这使得 PassTemplate 可被发现,以便其他通道可以按名称查找和引用它。注册 passTemplate 的方式取决于您是在数据(.pass
文件)还是 C++ 代码中创作它。
- Data: 如果在
.pass
文件中创作,则必须将该文件的路径添加到 pass 注册表中的 PassTemplates 列表中 (PassTemplates.azasset
). - Code: 如果用 C++ 编写,则必须在代码中将 PassTemplate 添加到 PassSystem。作步骤:
- 在初始化期间创建 PassTemplate。
- 调用
PassSystemInterface.Get()->AddPassTemplate(...)
. 这可以在 Atom API 参考的PassSystem.h
和PassLibrary.h
文件中找到。
实例化 Pass
您可以通过四种方式通过 PassSystem 实例化 Pass,所有这些方式的性能都相同:
将你想要的通道的类直接用作函数模板参数。这将调用该传递类的
static Create(...)
函数。使用要实例化的 pass 类的 Name。PassSystem 将使用 Name 来查找相应的 PassCreator(PassSystem 保存着一个 PassCreator 的映射,它可以使用 Name 进行索引)。PassCreator 只是一个函数指针,指向 Pass 的
static Create(...)
函数。使用 PassTemplate 或 PassTemplate 的 Name (它将使用 Name 从 PassSystem 查询 PassTemplate)。PassTemplate 具有用于查询 PassCreator 的 Pass 类的 Name,与步骤 2 相同。
使用 PassRequest(
PassRequest.h
)。PassRequest 是一个小型数据集合,详细说明了如何实例化 PassTemplate。这包括 PassTemplate 的 Name(如步骤 3 中所示)和 PassConnections 列表(PassAttachment.h
) ,用于将实例化的 Pass 与其邻居相关联。
注意:文件 PassRequest.h
和 PassAttachment.h
可以在 Atom API 参考中找到。
下面的示例代码演示了实例化传递的不同方法。
// 假设我们已经创建了一个名为 MyPassClass 的 Pass 类和相应的 MyPassTemplate,并分别以“MyPassClassName”和“MyPassTemplateName”的名称将它们注册到 PassSystem 中
// 示例 1:将 pass 类用作模板参数
Ptr<Pass> myPass1 = PassSystemInterface::Get()->CreatePass<MyPassClass>(Name("MyPassInstance1"));
// 示例 2:使用传递类的名称,以便 PassSystem 查询已注册的 Create() 函数并创建传递
Ptr<Pass> myPass2 = CreatePassFromClass(Name("MyPassClassName"), Name("MyPassInstance2"));
// 示例 3:使用通行证模板的名称,以便 PassSystem 查询已注册的通行证模板并使用它来创建通行证
Ptr<Pass> myPass3 = PassSystemInterface::Get()->CreatePassFromTemplate(Name("MyPassTemplateName"), Name("MyPassInstance3"));
// 示例 4:使用通行证模板的名称创建 PassRequest,以便 PassSystem 查询已注册的通行证模板并使用它来创建通行证
PassRequest myPassRequest;
myPassRequest.m_name = Name("MyPassInstance4");
myPassRequest.m_templateName = Name("MyPassTemplateName");
Ptr<Pass> myPass4 = PassSystemInterface::Get()->CreatePassFromRequest(&myPassRequest);
自定义通道实例化
待办:在这里为此任务创建一个GitHub问题。