Chapter 103: Rendering Pipeline Patterns
读完本章后,读者应能把一帧游戏画面拆成可维护的渲染管线结构,判断一个引擎应该使用固定顺序、Forward、Deferred、Render Graph、GPU-driven 或混合 Ray Tracing 中的哪一类模式,并能追踪 pass、资源声明、平台适配和性能证据之间的关系。
本章用一帧“室外城市关卡”作为贯穿材料:画面里有地形、静态建筑、带骨骼动画的角色、玻璃窗、局部体积雾、阴影、屏幕空间环境遮蔽、Bloom、调试叠层和 UI。这个 frame 的输入来自 scene graph、visibility result、material table、camera、light list、shadow settings 和平台能力表;输出是 swapchain 上的最终颜色,以及 profiler 中每个 pass 的 CPU 提交时间、GPU 时间、显存峰值和资源转换次数。
渲染管线模式的核心问题是“把一帧的渲染工作组织成什么结构”。固定顺序能降低早期工程复杂度,Forward 管线适合透明和 MSAA 密集场景,Deferred 管线把复杂光照集中到屏幕空间,Render Graph 用资源依赖组织 pass,GPU-driven 把可见性和 draw 参数生成移到 GPU,混合 Ray Tracing 把少数高价值路径交给光线查询或硬件加速结构。模式选择的结论来自 frame 的资源路径、API 状态、shader 变体、平台能力和性能证据。
本章讨论的是引擎架构层面的管线模式,后续单章会分别展开 Forward、Deferred、SRP、Render Graph 和具体引擎集成。本章只建立选择和设计框架:先确定视觉目标和数据输入,再把 pass 边界、资源生命周期、平台能力和性能瓶颈放到同一张依赖图里判断。
103.1 游戏引擎渲染架构演进与经典模式
游戏引擎渲染架构的演进可以从“谁决定一帧顺序”来理解。早期固定管线由 API 和硬件暴露一组有限状态,开发者按约定提交顶点、材质和光照状态。现代引擎把一帧拆成多个可编程 pass,每个 pass 声明输入、输出、shader、pipeline state 和同步边界。架构从固定步骤走向可组合图结构,原因来自材质复杂度、动态光源数量、后处理链、平台差异和调试需求共同增长。
在城市关卡这一帧里,最朴素的顺序是 shadow → opaque → transparent → postprocess → UI。这个顺序可以渲染出结果,但它把资源生命周期藏在代码调用顺序里:阴影贴图什么时候写完、深度什么时候供 SSAO 读取、HDR color 什么时候进入 Bloom、透明物体是否依赖 scene color,都需要开发者在每段代码里手工维护。随着 pass 数量增加,手写顺序会把问题从“画什么”推向“当前纹理处于什么状态、谁还会读它、何时释放它”。
Forward Rendering 的工作方式是让每个可见物体在自己的 draw call 中完成材质和光照计算。输入是 mesh、material、camera、per-object constant 和 light data,shader 在 fragment 阶段输出最终颜色。它的优势来自路径直接:透明物体、多采样抗锯齿和移动端 tile-based GPU 常能获得清晰的数据路径。代价也明确:多个光源会重复进入每个物体的 shading loop,材质和光照组合会推高 shader variant 数量,CPU 侧 draw 和状态切换也会增加。
Deferred Rendering 把几何阶段和光照阶段拆开。第一阶段把屏幕上可见表面写入 G-buffer,例如 normal、albedo、roughness、metallic、depth 和 motion vector;第二阶段在屏幕空间读取这些 attachment 计算光照。它把复杂光照从“每个物体重复执行”改为“每个像素集中执行”,适合大量动态光源和屏幕空间效果。代价是 G-buffer 占用显存带宽和 render target 数量,透明物体仍需单独路径,MSAA 的成本也会明显上升。
Render Graph 把一帧表达成 pass 和资源的依赖关系。pass 声明读取哪些 texture、写入哪些 buffer、使用 raster 还是 compute,图构建器再推导执行顺序、资源别名、barrier 和 lifetime。Unreal Engine 的 Render Dependency Graph 文档把 RDG pass parameters、资源访问声明、raster pass render target binding 和 load action 作为核心接口,说明现代引擎会把资源读写从隐式调用顺序提升到显式声明层。Unreal Engine 5.7 RDG 文档可以作为这种设计的工程参照。
GPU-driven Rendering 把可见性筛选、LOD 选择、instance compaction、indirect draw 参数生成等任务放进 compute pass。CPU 提供粗粒度场景数据和调度边界,GPU 在 buffer 中生成可提交的 draw 参数。它适合海量实例、开放世界、粒子或植被系统。它改变的瓶颈是 CPU 提交和可见性遍历,同时引入 compute 到 graphics 的同步、indirect buffer 状态和 GPU 调试难度。
Hybrid Ray Tracing 把部分效果交给 ray query、ray tracing pipeline 或硬件 RT 单元,例如反射、阴影、环境光遮蔽或全局光照的局部路径。它通常和 raster 主路径共存:光栅化负责主要可见表面,ray tracing 负责少量高价值采样,再通过 temporal accumulation、denoise 和 fallback 进入最终画面。它的架构成本来自 acceleration structure 更新、ray payload、shader table、平台能力和时域稳定性。
这几类模式的比较应使用同一组维度:frame 数据入口、pass 边界、资源生命周期、光照组织、透明路径、平台能力、调试证据和性能瓶颈。用城市关卡 frame 判断时,静态建筑和角色适合放进 opaque 主路径,玻璃窗需要 transparent 路径,阴影和 SSAO 依赖深度,Bloom 依赖 HDR color,UI 在 tone mapping 后合成。模式选择的第一步是把这些依赖画出来,而非先套某个引擎名词。
下图把本章使用的 frame 组织成最小依赖图。它省略了具体 API 调用,只保留 pass、资源和最终画面之间的关系。
这张图的关键点是资源驱动顺序。Shadow pass 产出 shadow map,Opaque pass 同时产出 depth 和 HDR color,SSAO 读取 depth,Bloom 读取 HDR color,Composite 收束多个中间结果,UI 在最终颜色空间附近合成。Render Graph 模式会把这张图转成 pass 调度和资源 lifetime;传统顺序模式则要求开发者在代码里手动保持同样的依赖。
103.2 基于管线的分层渲染结构设计
分层渲染结构的目标是把一帧拆成稳定层级,让功能迭代、平台适配和性能定位都能找到明确归属。对城市关卡 frame,可以把渲染系统分成五层:场景采集层、可见性层、pass 构建层、后端提交层和工具观测层。每一层都有独立输入和输出,层之间通过数据结构连接。
场景采集层负责从 engine world 收集渲染输入。它读取 transform、mesh handle、material handle、animation pose、light component、reflection probe、camera 和 quality setting,输出 renderer 可消费的 frame data。它的边界是“只收集当前帧所需的渲染事实”,例如角色骨骼矩阵、建筑实例列表和光源参数。资源加载、编辑器资产导入和物理模拟属于上游系统,进入本层时应已经转成稳定的渲染句柄或快照。
可见性层负责把 frame data 转成 renderable list。它执行 frustum culling、occlusion result 复用、LOD 选择、material sorting 和 render queue 分类。输出可以是 opaque list、transparent list、shadow caster list、skinned list 和 GPU-driven input buffer。这个层级的判断证据来自可见物体数量、被剔除数量、LOD 分布、draw call 分组和排序后 pipeline state 切换次数。
pass 构建层负责描述一帧“需要哪些工作”。在传统架构里,它可能是一串函数调用;在 Render Graph 架构里,它是若干 pass declaration。一个 pass declaration 至少应包含 pass 名称、执行类型、输入资源、输出资源、camera 或 light 输入、shader 或 material route、viewport、clear/load action、debug marker 和 profiling scope。Unity 的 Scriptable Render Pipeline 文档说明 SRP 通过 C# 脚本调度和配置渲染命令,并由低层图形架构发送到图形 API;这个描述正好对应 pass 构建层和后端提交层的分工。Unity 6.4 SRP fundamentals提供了相关接口边界。
后端提交层负责把 pass declaration 转成具体 API 命令。它处理 pipeline state object、descriptor 或 bind group、render target binding、barrier、command buffer、queue submit 和 present。这个层级必须吸收 API 差异,例如 Vulkan 显式 layout transition、Direct3D 12 resource state、Metal command encoder、WebGPU pass encoder 和 OpenGL 隐式状态。它的输出是 GPU 可执行命令流。
工具观测层负责让工程师能把视觉结果和性能症状定位回管线。每个 pass 应产生 debug marker、GPU timestamp、CPU build time、resource allocation peak、attachment size 和 shader variant 信息。RenderDoc 可观察 draw call 状态和资源绑定,Nsight 可观察 GPU 执行与 stall,Xcode GPU tools 可观察 Metal command encoder 和 tile memory 行为。工具观测层的边界是“回答这一帧发生了什么”,它不替代架构设计,但能验证架构判断。
分层结构提高可维护性的原因是依赖方向清晰。新增屏幕空间反射时,场景采集层只需提供反射质量参数,pass 构建层新增 SSR pass,后端提交层负责资源状态和 pipeline,工具观测层新增 marker 和 timing。每一层改变的对象不同,代码审查和性能回归都能沿着层级定位。
一个稳定的分层渲染结构可以用下面的接口边界表达:
struct FrameRenderInput {
CameraData camera;
RenderableList opaqueObjects;
RenderableList transparentObjects;
LightList lights;
QualityProfile quality;
PlatformProfile platform;
};
struct RenderPassDesc {
string name;
PassType type;
ResourceReadList reads;
ResourceWriteList writes;
PipelineStateKey pipeline;
DebugScope debugScope;
};
struct RenderFramePlan {
vector<RenderPassDesc> passes;
ResourceLifetimeTable resources;
};
这段简化代码展示的是数据边界,属于经过压缩的引擎实现模型。FrameRenderInput 对应当前帧的场景事实,RenderPassDesc 对应 pass 声明,RenderFramePlan 对应可执行前的帧计划。实际工程会把资源句柄、descriptor、queue、allocator、shader variant 和平台扩展拆得更细,但核心关系保持一致:上层描述要渲染什么,中层描述 pass 和资源,下层生成 API 命令。
103.3 构建可扩展渲染管线框架
可扩展渲染管线框架的重点是把 pass 变成可声明、可排序、可观测、可替换的对象。对城市关卡 frame,框架要支持 shadow、depth prepass、opaque、SSAO、lighting、transparent、postprocess、UI 和 debug overlay,并允许不同平台开启或关闭其中一部分。扩展能力来自接口约束,而非来自无限制回调。
pass interface 应先表达资源契约。一个 pass 需要声明读取资源、写入资源、访问方式、尺寸、格式、采样数、queue 类型和 clear/load 行为。声明越完整,框架越能推导 lifetime、aliasing、barrier 和调试信息。Vulkan 同步示例文档把 compute 写入 storage image 后由 fragment shader 读取的路径表达为 stage、access 和 image layout 的转换,这说明后端需要知道“谁写、谁读、在哪个阶段读写”。Khronos Vulkan synchronization examples支撑的正是这种资源契约思路。
resource declaration 应区分逻辑资源和物理资源。逻辑资源是 SceneDepth、HDRColor、SSAOTexture、BloomMipChain 这类 frame 内名称;物理资源是 API 后端分配的 texture、buffer、heap 或 memory allocation。框架先让 pass 使用逻辑资源表达依赖,再由 allocator 根据 lifetime 复用物理内存。这样做可以降低显存峰值,也能在 debug view 中用稳定名称追踪资源。
camera 和 light input 应作为 frame data 的显式部分进入 pass。Shadow pass 读取 light view-projection 和 shadow caster list;Opaque pass 读取 camera matrix、visible objects、material table 和 shadow map;Lighting 或 composite pass 读取 light list、G-buffer 或 HDR color;Transparent pass 读取 scene depth、scene color 和 sorted transparent list。显式输入能让 pass 在编辑器、回放、测试和离线捕获中复用。
debug marker 和 profiling hook 应成为 pass interface 的固定字段。每个 pass 的名称、分组、视口、输出资源和 GPU timing 都应能在 capture 中对应到源码构建点。没有 marker 的 pass 会让工程师只能从 API 调用倒推功能,复杂项目里很快失去定位能力。profiling hook 还应记录 CPU 构建时间,因为 Render Graph 编译、资源分配、排序和剔除本身也会产生 CPU 开销。
框架应允许 pass 使用稳定的增量扩展方式。新增体积雾时,工程师可以声明 VolumetricFog pass 读取 depth、froxel volume、light list 和 shadow map,写入 fog texture,再由 Composite pass 读取。新增 debug normal view 时,可以声明 DebugNormal pass 读取 G-buffer normal,写入 debug overlay。可扩展性来自资源依赖自动连接,功能代码不需要侵入所有旧 pass。
下面是一个简化的 pass 注册流程,用来说明框架怎样把功能代码收敛成 frame plan:
void BuildCityFrame(RenderGraph& graph, const FrameRenderInput& input) {
auto shadowMap = graph.CreateTexture("ShadowMap", ShadowFormat(input.quality));
auto depth = graph.CreateTexture("SceneDepth", DepthFormat(input.platform));
auto hdr = graph.CreateTexture("HDRColor", HDRFormat(input.platform));
auto ssao = graph.CreateTexture("SSAO", LowResAOFormat());
graph.AddRasterPass("Shadow", {}, {shadowMap}, [&](CommandContext& cmd) {
DrawShadowCasters(cmd, input.lights, input.opaqueObjects);
});
graph.AddRasterPass("Opaque", {shadowMap}, {depth, hdr}, [&](CommandContext& cmd) {
DrawOpaque(cmd, input.camera, input.opaqueObjects);
});
graph.AddComputePass("SSAO", {depth}, {ssao}, [&](CommandContext& cmd) {
DispatchSSAO(cmd, input.camera);
});
graph.AddRasterPass("Composite", {hdr, ssao}, {graph.BackBuffer()}, [&](CommandContext& cmd) {
CompositeLightingAndPost(cmd, input.camera);
});
}
这段伪代码展示了四个工程判断。第一,pass 声明以资源读写为中心。第二,函数体只提交当前 pass 的命令,不负责全局资源状态。第三,ShadowMap、SceneDepth、HDRColor 和 SSAO 是逻辑资源名,后端可推导物理分配和 barrier。第四,debug marker 可以直接沿用 pass 名称,让工具捕获和源码结构一致。
可扩展框架还需要失败路径。资源格式不受支持时,HDR color 可以降级到较低精度格式;timestamp query 不可用时,profiling hook 只记录 CPU 时间;compute queue 不适合某平台时,SSAO 可以回到 graphics queue;透明路径过重时,质量档位可以关闭低价值透明后处理。失败路径必须进入 profile 或 quality system,由 frame plan 统一决定。
103.4 多平台渲染适配问题与解决
多平台适配的主问题是同一套渲染设计如何落到不同 API、GPU 架构和设备限制上。城市关卡 frame 在 PC、主机、移动端和 Web 上都可能存在同样的视觉目标,但资源格式、shader 语言、同步模型、内存预算、MSAA 支持和 timestamp 能力不同。跨平台渲染架构需要把差异放进 platform profile,而非散落在每个 pass 的条件分支里。
API 能力差异首先体现在资源和同步。Vulkan 使用显式 image layout、access mask 和 pipeline stage 来描述读写依赖;Direct3D 12 使用 resource state 和 barrier 表达资源转换;Metal 通过 command encoder、resource usage 和平台约束组织命令;WebGPU 通过 device limits、feature 和 pass encoder 提供更受限的跨浏览器抽象。统一框架应把这些差异归纳成引擎内部的 access model,例如 ColorAttachmentWrite、ShaderRead、StorageWrite、CopySrc 和 Present。
shader 方言差异来自语言、编译器和资源绑定模型。HLSL、GLSL、MSL、WGSL 和 SPIR-V 的入口语义、矩阵约定、纹理采样语法、descriptor 组织和精度限定并不完全一致。稳定做法是先定义引擎 shader interface:camera buffer、object buffer、material texture set、light buffer、sampler set 和 push constant 或 root constant,再由平台后端生成对应绑定布局。shader 变体 key 应包含 feature toggle、quality tier、material path、platform backend 和 render pass type。
格式支持差异会直接改变 pass 设计。HDR color 在桌面端可能使用 RGBA16F,移动端可能使用更节省带宽的格式,Web 端还要考虑浏览器暴露的 texture format 和 canvas 配置。G-buffer 的 normal 可以使用双通道编码,roughness 和 metallic 可以打包到同一 attachment,motion vector 可以按质量档位开关。格式选择应跟带宽、精度、工具可读性和后续 pass 的采样需求一起判断。
同步模型差异影响 Render Graph 后端。一个 pass 写入 HDRColor,下一个 compute pass 读取它做 Bloom,后端需要在具体 API 中插入合适 barrier 或 encoder 边界。抽象层需要同时记录“先后顺序”、读写阶段和访问方式。这样才能在 Vulkan 中生成 layout transition,在 D3D12 中生成 state transition,在 Metal 中选择合理 encoder 和 resource usage,在 WebGPU 中满足 pass 边界和绑定规则。
资源限制决定 fallback 设计。移动端可能受限于 tile memory、attachment 数量、纹理尺寸、带宽和热功耗;Web 端受限于浏览器 device limits、worker 支持和上下文丢失;桌面端也会被 descriptor 数量、pipeline cache、VRAM 和驱动行为限制。platform profile 应在初始化时收集 feature、limits、format support 和 performance class,再把结果传给 frame plan。
一个可维护的平台适配表应表达“能力 → 管线决策”的映射:
| 平台能力 | 管线决策 | 观察证据 |
|---|---|---|
| MRT 数量充足且带宽预算充足 | 允许完整 G-buffer | attachment 数量、RT 格式、GPU bandwidth |
| MSAA 成本受控且透明较多 | 优先 Forward 或 Forward Plus | sample count、透明 draw 比例、resolve 成本 |
| Compute 和 indirect draw 支持稳定 | 启用 GPU-driven culling | compute time、indirect buffer barrier、CPU submit time |
| Storage texture 或高精度格式受限 | 降级屏幕空间效果 | format support、visual diff、fallback marker |
| Timestamp query 不稳定 | 使用 CPU marker 加少量工具捕获复查 | profiler 数据完整性、capture 可读性 |
这张表的价值在于把平台差异转成可审查的决策。工程师看到某个设备关闭 Deferred 或关闭 SSR 时,可以追踪到能力查询、质量档位和性能证据,也能减少在 pass 代码里搜索散乱宏分支的成本。
fallback path 应保持视觉和性能目标可解释。SSR 关闭时可回到 reflection probe;高质量 SSAO 关闭时可使用低分辨率 AO;GPU-driven culling 关闭时可使用 CPU visibility list;HDR 格式降级时需要重新检查 tone mapping 和 Bloom 阈值。fallback 的目标是让 frame plan 在能力不足时仍然生成闭合的 pass 图,并在 debug overlay 中显示当前路径。
103.5 性能考量:引擎通用性与效率的平衡
通用渲染架构的成本来自抽象层、资源声明、pass 编译、shader variant、状态转换和平台分支。效率来自批处理、资源复用、稳定排序、后端专用优化和可观测 profiling。平衡点应落在可验证收益上:每一层抽象都要换来明确的正确性、可维护性或性能收益,并且它的 CPU、GPU、显存和调试成本可被测量。
抽象成本首先体现在 CPU frame time。Render Graph 构建会遍历 pass、解析资源依赖、分配物理资源、生成 barrier、排序命令和写入 marker。小型项目可能用固定顺序获得更低 CPU 开销;大型项目通过 Render Graph 换来资源 lifetime 管理、自动同步、pass 裁剪和调试一致性。判断依据应来自 CPU profiler:graph build time、pass count、resource count、barrier count 和 command recording time。
batching 决定 draw 提交效率。Forward 和 Deferred 主路径都需要 material sorting、instance batching、meshlet 或 cluster 分组、descriptor 缓存和 pipeline state 复用。通用材质系统如果允许任意 feature toggle,会制造大量 shader variant 和 pipeline state。效率路径是把材质特性收束成稳定 key,例如 surface type、blend mode、lighting model、shadow receive、normal map、skin flag 和 platform tier,再按 key 排序提交。
resource lifetime 决定显存峰值和带宽。Render Graph 可以根据 pass 依赖释放或复用临时资源,例如 SSAO、Bloom 中间 mip、temporary depth pyramid 和 debug buffer。资源别名可以降低显存峰值,但会增加调试难度,因为同一物理 texture 在 frame 内代表多个逻辑资源。工程上应保留逻辑资源名、lifetime 可视化和 aliasing 开关,用于定位误写、未初始化 load 和错误读写。
platform specialization 决定后端效率。统一 pass interface 给架构带来一致性,但后端需要为不同 API 生成不同提交策略。Tile-based GPU 上应重视 load/store action、render pass 合并和 attachment 写入;桌面 immediate-mode GPU 上应重视 barrier 粒度、descriptor 更新、pipeline cache 和异步 compute;Web 端应重视 JS 到 GPU 的提交次数、buffer upload 和 shader compile hitch。平台专用优化应位于后端和 profile 层,业务 pass 保持资源契约稳定。
性能判断顺序应固定。第一步确认 CPU 和 GPU 谁是主瓶颈,使用 frame time、GPU timestamp 和 command recording time 区分。第二步定位最重 pass,检查 draw count、dispatch count、attachment size、shader time、texture bandwidth 和 barrier。第三步追踪资源路径,看临时纹理是否过大、格式是否过宽、load action 是否要求保留旧内容、compute 到 graphics 是否造成等待。第四步再决定优化动作,例如合并 pass、降低格式、调整 batching、压缩 G-buffer、关闭低收益 effect 或为平台写专用路径。
城市关卡 frame 的一个典型诊断是 Bloom 和 SSAO 看起来只占少量画面,但 GPU 时间异常高。正确排查路径是先看它们的输入 texture 尺寸和格式,再看 dispatch 尺寸、mip chain 数量、读写 barrier、cache 行为和与主队列的同步。若 Bloom 使用全分辨率 RGBA16F 多次读写,降到半分辨率并复用 mip chain 可能比改 shader 算法更有效。若 SSAO 每帧重建 depth pyramid 且后续 pass 只用一个 mip,裁剪无用 mip 会直接减少带宽和 dispatch。
通用性与效率的平衡最终要落到工程规则:公共路径负责正确性、可观察性和跨平台一致;平台 profile 负责能力差异;后端负责 API 专用优化;质量系统负责可控降级;工具层负责证明优化是否有效。这样,渲染管线既能容纳不同项目需求,也能在具体 frame 上给出可测量结果。
最小自检任务
给定一个简化 frame:场景有 2,000 个不透明建筑实例、20 个动态点光源、少量玻璃窗、一个角色、SSAO、Bloom 和 UI。目标平台包括桌面 PC 和移动端。请设计一个最小渲染管线模式,说明你会选择 Forward、Deferred、Render Graph、GPU-driven 或混合方案中的哪些部分,并写出 pass 顺序、关键资源、平台 fallback 和第一轮性能排查顺序。
答案要点
合格答案应先把 frame 拆成可见性、shadow、opaque 或 G-buffer、lighting、transparent、postprocess、UI 和 present。桌面 PC 可以选择 Deferred 或 Deferred 加 Forward transparent:G-buffer 写 normal、albedo、material、depth,lighting pass 处理 20 个点光源,玻璃窗走 Forward transparent,SSAO 读取 depth,Bloom 读取 HDR color。移动端需要根据 MRT 数量、带宽和 MSAA 需求判断,若 G-buffer 带宽过高,可改用 Forward 或 Forward Plus,并降低 SSAO、Bloom 分辨率。
关键资源应包括 shadow map、scene depth、HDR color、G-buffer attachments 或 forward color、SSAO texture、Bloom mip chain 和 back buffer。Render Graph 部分应让每个 pass 声明读写资源,用逻辑资源名推导 lifetime、barrier 和 debug marker。GPU-driven 部分可用于 2,000 个建筑实例的可见性压缩和 indirect draw,但移动端 fallback 可以回到 CPU visibility list。
性能排查顺序应先区分 CPU 和 GPU 主瓶颈,再看最重 pass 的 GPU timestamp、draw count、attachment 尺寸、shader cost 和带宽。若 CPU 提交过高,优先检查 batching、instance 分组、material sorting 和 command recording。若 GPU 带宽过高,优先检查 G-buffer 格式、Bloom 分辨率、load action、depth pyramid 和临时资源 lifetime。答案还应说明平台 fallback 的证据来源:feature、limits、format support、timestamp 可用性和视觉差异。
本章知识点总结
- 管线模式:渲染管线模式决定一帧工作如何拆成 pass、资源和提交边界。
- 演进主线:现代架构从固定顺序走向显式 pass 声明和资源依赖图。
- Forward 路径:Forward 把材质和光照放进每个物体的 draw 中,适合透明和 MSAA 密集场景。
- Deferred 路径:Deferred 先写 G-buffer 再做屏幕空间光照,适合动态光源较多的场景。
- Render Graph:Render Graph 通过 pass 读写声明推导执行顺序、资源生命周期和 barrier。
- GPU-driven:GPU-driven 把可见性、LOD 和 indirect draw 参数生成移到 GPU buffer 路径。
- 混合光追:Hybrid Ray Tracing 把高价值反射、阴影或 GI 采样接入 raster 主路径。
- 分层结构:场景采集、可见性、pass 构建、后端提交和工具观测应保持清晰边界。
- Pass 契约:可扩展框架应让 pass 显式声明输入、输出、访问方式、debug marker 和 profiling hook。
- 逻辑资源:逻辑资源名用于表达 frame 依赖,物理资源由后端 allocator 根据 lifetime 分配或复用。
- 平台画像:platform profile 应集中记录 feature、limits、format support 和性能等级。
- Shader 接口:跨平台 shader 适配应围绕引擎统一 buffer、texture、sampler 和变体 key 设计。
- Fallback 路径:降级路径应从能力查询和质量档位生成,并能在 debug overlay 中追踪。
- 抽象成本:通用架构的 CPU 构建、barrier、shader variant 和资源管理成本都需要测量。
- 性能顺序:排查时先分离 CPU 与 GPU,再定位 pass、资源格式、带宽、同步和提交开销。
- 最终判断:一个合格渲染管线既要能表达视觉目标,也要能被工具证据验证和跨平台落地。