渲染与抓帧研究

本文整理 Orbit 的本地学习记录。案例结论限于记录中的游戏版本、捕获和研究样板,不代表完整原作实现。文中的 ArtSource 路径是本地证据索引;工程当前约束与验收要求由 Orbit 项目文档维护。

从建模到最终画面

制作流程决定资产怎样产生,渲染流程决定 GPU 怎样使用这些资产。RenderDoc 能观察后者,不能还原作者的概念设计、Blender 修改器、原始拓扑编辑历史或完整工程。抓帧研究用于理解成熟作品的做法,再用原创资产实现合适的方案。

阶段 做什么、为什么 进入下一阶段前看什么
探索设计与灰盒 确定尺度、路线、落点、地标和视线;先验证空间可用 地面能辨认路径,轨道上能辨认目的地
模块建模 分开地形、岩壁、植被和建筑;用轮廓与几何表达重要形状 纯灰材质下轮廓清楚、比例可信、入口可通行
法线、UV 与贴图 处理硬边、切线和 UV;绘制颜色、法线及混合遮罩 贴图不拉伸,远近细节层次一致,材质分区自然
引擎资产准备 统一坐标与单位,配置碰撞、分块、实例复用、LOD 或适用的 Nanite 原始网格与导入结果一致,碰撞和可见性符合用途
材质与场景装配 用共享材质和实例控制变化;在真实关卡中组合模块 未照明视图中的底色正确,参数变化不会破坏同系列风格
光照与后处理 联调太阳、环境光、局部灯、雾、曝光和色调映射 昼夜、地面与轨道视角均可读,不靠曝光掩盖材质错误
画面与性能验收 固定机位比较,再实际移动、旋转和穿行 视觉、运动稳定性和帧时间同时达标

《星际拓荒》官方解释了硬边模块化岩石如何服务路径识别,以及几何细节、贴图大色阶、动态太阳和球形雾如何共同形成画面。学习它应先理解这些关系,再决定原创星球的造型与材质。木炉星美术制作说明

一帧怎样被画出来

Mesh 是顶点与三角形;Texture 是 Shader 读取的数据;Material 组织 Shader 和参数;Shader 在 GPU 上执行计算;Pass 是为某个目的执行的一组渲染工作;Draw 是一次绘制提交。一个 Mesh 可以因阴影、深度、底色等用途被多次绘制,Draw 数量不等于独立模型数量。

下面是常见延迟渲染的学习示意,具体游戏的顺序、资源格式与额外阶段必须从实际捕获确认;它不是木炉星已验证的完整渲染流程。

1
2
3
4
5
6
7
8
flowchart LR
A[网格、贴图、材质参数] --> B[顶点处理与光栅化]
B --> C[GBuffer:表面颜色、法线等]
S[阴影结果] --> D[光照计算]
C --> D
D --> E[透明物体、雾等场景效果]
E --> F[曝光、色调映射等后处理]
F --> G[屏幕画面]

VS(顶点 Shader)常负责顶点位置变换并输出可插值数据;PS(像素 Shader)常负责采样贴图、计算表面属性或颜色。延迟渲染的表面 Pass 通常写入 GBuffer 中间纹理,最终灯光和屏幕颜色还要经过后续阶段。因此,只搬模型和表面材质,不能保证最终画面一致。

Base Color/Albedo 是表面的底色;Normal 描述着色时使用的表面方向,不会直接改变轮廓;Roughness 控制反射的锐利或模糊;Metallic 控制金属性质;AO 表达局部遮蔽,不能替代所有实时阴影。UV 告诉 Shader 到贴图的哪里取样,顶点颜色也可以存混合权重。一张贴图的 RGBA 四个通道可能存不同数据,Alpha 不一定表示透明度。

颜色贴图常用 sRGB 编码,Shader 中的颜色计算通常在线性空间进行;法线、粗糙度、遮罩等数值数据不应随意进行 sRGB 转换。把颜色和数据用错色彩空间,会改变底色或混合权重,不能靠调灯补救。

RenderDoc 与 AI/MCP 的研究流程

用户提供的《RenderDoc — 打造自己 AI 工作流》演示了用 AI/MCP 分析帧流程、研究效果、导出依赖并在 Unity 重建;作者也记录了贴图与选取范围问题。本文把这种方法用于 Blender 与 UE,并以原始数据和画面对比校验 AI 的推断。文中的终末地技术不能直接当成木炉星的实现。

RDC 和工具各负责什么

.rdc 保存一帧的图形 API 调用、状态及重放所需的资源内容。它体积大,主要因为包含贴图和缓冲数据;具体占比需要统计,不能仅凭文件大小判断模型复杂度。它能包含镜头外但被该帧引用的资源,也可能缺少未加载或未引用的区域。捕获与重放原理

AI 客户端通过 MCP 服务请求数据,RenderDoc 扩展访问当前捕获和重放 API;本项目所用桥接通过文件 IPC 在两个进程之间传递请求。Blender 负责网格整理,UE MCP/Editor Python 负责引擎中的资产和场景操作。工具能自动读写数据,不能保证 Shader 推断正确。文章使用的桥接项目、本项目所用分支

不同游戏怎样捕获

各游戏的启动方式、权限/API 对照、抓帧快捷键、RDC 归档及 RenderDoc 故障修正统一维护在 RenderDoc 本机抓帧文档(本地文件:C:/Users/error/Repos/renderdoc/docs/local-game-captures.md)。本节只保留移植研究与素材使用的关系;不要在 Orbit 再复制一套启动参数。

阅读与重建捕获

打开 RDC 后按这个顺序看

先用 File → Open Capture 打开捕获,选一块岩壁或一棵树作为目标;先研究一个对象,确认正确后再扩大范围。以下窗口中的数据随所选事件变化。

顺序与窗口 操作与问题 应获得的证据
1. Event Browser 沿事件顺序观察中间结果;定位目标被绘制的事件 Event ID、所在 Pass、输入输出资源;暂不能确定的用途单独标记
2. Pipeline State 检查顶点输入、VS/PS、资源绑定、深度、剔除和混合设置 这个对象实际使用的缓冲、贴图槽、参数与渲染状态
3. Mesh Viewer 对照 VS Input 与 VS Output;实例绘制要切换 Instance 顶点属性、索引、局部几何、实例差异及变换后的结果
4. Texture Viewer 查看绑定纹理的 RGBA、mip 和格式,检查输出中间纹理 颜色、法线、遮罩或其他数据的候选含义;由 Shader 的用法进一步确认
5. Shader Viewer 与常量缓冲 追踪采样、乘法、混合、裁剪和矩阵计算 贴图、参数到输出之间的实际计算链
6. Pixel History / Shader 调试 在受支持的 API 与事件上追踪目标像素 哪些绘制改写该像素、在哪一步出现颜色或遮挡差异

Shader Viewer 有源码调试信息时可以显示源码,否则通常只能得到编译后的反汇编;不能把反编译推断称为原作者源码。Mesh Viewer 的变换后预览也可能使用估计的投影参数,不应直接当作精确相机。官方 Mesh Viewer、Pipeline State、Texture Viewer、Shader Viewer

从捕获数据到 UE 的重建

  1. 确定范围与依赖。 从目标事件出发,沿资源读写关系查找相关阶段,区分表面、阴影、辅助和透明绘制。不要把同一几何的不同 Pass 当成不同物体反复导出。
  2. 恢复几何与摆放。 读取顶点输入和索引,再确定物体与实例矩阵。普通网格优先研究 VS Input;动画、风和程序化变形还需要分析 VS,输入网格可能不是屏幕上最终形状。
  3. 确认纹理与参数。 保存绑定关系、格式、UV 变换和常量值,区分 sRGB 颜色与线性数据。贴图通道用途由实际计算确认,不能只按图片看起来像什么判断。
  4. 重写可验证的材质计算。 把已确认的公式转换成 UE 节点或 Custom HLSL,再匹配透明裁剪、双面、深度等设置;未还原的部分明确保留为近似。
  5. 逐阶段比较。 先对照几何和未照明底色,再比较法线与表面属性,最后补光照、雾、透明效果、曝光和色调映射。每次只调整一个影响来源。
  6. 整理为可用资产。 保留模块和实例复用关系,配置可见性、LOD/适用的 Nanite、碰撞和性能预算。研究用导出结果不能直接当成生产资产。

坐标与矩阵要单独验证:物体局部坐标先通过物体矩阵进入世界,再通过相机和投影进入裁剪空间。Unity、Blender、UE 的轴向、单位、手性和导入器处理不同;错误会导致镜像、反面或相机翻转。法线在非均匀缩放时需要逆转置矩阵,不能直接当位置变换。常量缓冲还包含对齐、矩阵布局和整数位模式,不能把每个值都当普通浮点参数。

一个简化的表面例子是 BaseColor = ColorTexture × Tint,岩石与草地可以通过遮罩 w 做 lerp(Rock, Grass, w),树叶可用 Alpha 与阈值进行裁剪。真实遮罩可能组合坡度、高度、顶点色和贴图;有些法线还采用打包编码。重建时必须以所选 Shader 的公式与数据为准,这些例子不是所有游戏通用的解码规则。

UE 的共享主材质承载共用逻辑,材质实例负责资产间的参数变化。跨引擎时即使表面公式一致,光照模型、法线约定、阴影与后处理也可能不同;完成材质编译只证明它可执行,还需要画面对比。

导出与导入的本地操作示例

示例中的路径和 Event ID 由当前研究环境填写;$qrenderdocPath、$blenderPath、$editorCmdPath、$editorPath 分别指向本机工具,$PWD 为 Orbit 项目根目录。

先按素材研究流程(本地文件:Docs/content/assets.md)保存并回放 RDC,再选择目标绘制。RenderDoc 嵌入式 Python 使用 ExportGpuCapture.py;请求中的事件编号必须来自当前捕获,不能跨帧复用。输出目录保存中间数据,原始 RDC 可保留在仓库之外。

1
2
3
4
5
6
7
8
9
10
11
# 替换为自己的捕获、输出目录和已确认的 Event ID。
$taskRequest = @{
capture = $capturePath
output = $rawExportDirectory
events = $selectedEvents
frame = $verifiedFrameNumber
}
$taskRequest | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $requestPath
$env:ORBIT_CAPTURE_REQUEST = $requestPath
& $qrenderdocPath --python "$PWD\Scripts\Other\ExportGpuCapture.py"
Get-Content (Join-Path $rawExportDirectory 'export-status.json')

export-status.json 必须没有 error。补充已确认的纹理输入时,同一入口可使用 mode: textures、event 与资源 ID 列表 textures;它保留数组各层,浮点与 BC6 数据输出 EXR,来源记录在 textures.json。检查所选几何、索引和纹理槽后才重建模型。字符分支分别处理已确认的绝区零 D3D11 与终末地 Vulkan 布局;不同游戏/Shader 必须重新验证物体矩阵、UV 和常量布局,断言失败时不能跳过验证硬套。

1
2
& $blenderPath -b --factory-startup --python-exit-code 1 `
-P Scripts/Art/VerifyModelSources.py -- ../ArtSource/ZenlessZoneZero/CaptureStudy.blend

在 Blender 中整理已导出的场景和人物源。人物源检查应确认批次/面数、UV、材质、有限坐标和图片依赖,并明确其为定格网格。检查预览与原始捕获的左右方向、部件摆放和贴图;必要时输出多视角轮廓、灰模及线框。

UE 导入与检查共用现有入口;以下 $editorCmdPath 指向 UE 5.8 的 UnrealEditor-Cmd.exe,$editorPath 指向 UnrealEditor.exe,执行前保存并关闭其他使用本项目的 Editor。

1
2
3
4
5
6
7
8
& $editorCmdPath "$PWD\orbit.uproject" `
"-ExecutePythonScript=$PWD\Scripts\Art\ImportArtRevision.py" `
-ArtImport=reference -ArtReference=ZenlessZoneZero -unattended -nopause -nosplash

& $editorPath "$PWD\orbit.uproject" `
"-ExecutePythonScript=$PWD\Scripts\Art\VerifyArtRevision.py" `
-ArtCheck=reference -ArtReference=ZenlessZoneZero -ArtReferenceRender `
-unattended -nopause -nosplash -windowed

星际拓荒使用同一 UE 入口,-ArtReference=OuterWilds/Scenes/TimberHearth 选择木炉星;其他场景使用 OuterWilds/Scenes/<场景名>。验证材质编译、网格 UV/绑定、研究相机和无重定向,检查 UECaptureCamera.png 与 UEReviewCamera.png。截图完成后关闭本次检查实例。检查新增资产的来源路径、引用和 LFS 属性;不以简单分段着色的截图声称完成原作渲染管线或骨骼动画恢复。

太阳系总览复用上述入口的 -ArtImport=reference-overview 与 -ArtCheck=reference-overview。先同步各天体,再装配总览;检查各天体引用、坐标转换、重复网格和无重定向。验证时附加 -ArtReferenceRender 输出 UEOverview.png,核对实际构图与可见性。

人物蒙皮数据导出使用 skinning_events,仅填写已核实的流输出事件;核对 Shader、顶点对应与矩阵后再使用。GPU 矩阵表不包含原骨骼名称和父子层级,不能当成原装骨架。

画质与性能一起学习

木炉星研究样板说明:恢复网格可以帮助研究造型,但把整星的多次绘制合成一个普通大网格,会丢失原有分块与实例管理的优势。没有合适的细节控制时,转动镜头仍可能处理大量几何,阴影还会增加开销。暂时关闭动态投影是预览取舍,不能当成正式性能优化完成。

先固定机位、分辨率与运行环境,再区分 CPU、GPU 和内存瓶颈。比较帧时间而非只看面数:60 FPS 的整帧时间预算约为 16.7 ms。GPU 研究中还要看可见三角形、屏幕像素开销、树叶遮罩/双面重叠、材质采样、阴影和纹理内存;CPU 则可能受绘制提交与场景管理影响。

LOD 用不同距离或屏幕尺寸的网格降低细节;实例化让重复物体共享网格数据;分块允许按区域剔除。Nanite 提供自动细节管理和细粒度几何处理,但不能替代材质、植被重叠和阴影开销的测量,启用前仍需检查支持条件及实际结果。UE Nanite、虚拟阴影

最小验收顺序是:几何与坐标 → 材质绑定与底色 → 法线及透明遮罩 → 光照与后处理 → 实际移动和性能。技术检查入口与职责见验证(本地文件:Docs/engineering/verification.md);每步保存可比较的证据,不能用单张好看的截图替代运行检查。

学习练习与项目入口

先研究一块岩壁、一棵树和一段桥:分别练习地貌混合、透明遮罩与实例、普通表面材质。对每个目标回答“形状靠什么、颜色靠什么、光照增加了什么、性能花在哪里”,再在 UE 做一个对应的原创小样。

可以向 AI 提这样的请求:

只分析选中岩壁的绘制事件。列出输入网格、绑定贴图与参数,以及通向表面颜色和法线输出的计算。每个判断给出 Event ID、资源槽或 Shader 指令依据,区分已确认、推断和未解决项;先不要修改或导出整场景。

对比该对象的捕获结果与 UE 同机位画面,按几何、UV/色彩空间、材质、光照、后处理逐项定位差异,每次只验证一个因素。

当前项目使用 ExportGpuCapture.py(本地文件:Scripts/Other/ExportGpuCapture.py) 从选定 RDC 批次导出数据,在 Blender 中整理现有研究源,使用 ImportArtRevision.py(本地文件:Scripts/Art/ImportArtRevision.py) 批量导入,以及 VerifyArtRevision.py(本地文件:Scripts/Art/VerifyArtRevision.py) 检查绑定和输出画面。当前检查要求见验证(本地文件:Docs/engineering/verification.md),材质参数与来源证据保存在资产和研究源数据中。工具分工见Scripts(本地文件:Scripts/README.md)。