由 astra 生成 · 更新于 2026-09-27 18:44(北京时间)
分析日期:2026-09-27。范围为蕾米所在的室内大厅,输入为本机
leimi_all_resource.rdc。重点是压缩烘焙光、局部灯光、镜像反射、湿润表面和颜色/身份双历史。
本文完整展开本截帧的场景逻辑;角色内部算法见 角色分析。跨游戏结论另见 场景实现对比,回放定位见 证据索引。
总览用于定位场景;算法旁的局部图采用同一区域对照,并写明可观察的变化。阶段配对保持一致显示设置,HDR 预览范围与最终输出颜色分别说明。图片直接从真实回放生成,未修改截帧资源。
1. 管线与数据依赖
| 阶段 | 处理逻辑 | 输出的作用 |
|---|---|---|
| 几何与阴影准备 | 完成角色变形、翅膀细分,准备阴影代理 | 可见形状与遮挡形状分别交给对应视图 |
| 镜像视图 | 从镜像视点完成几何、照明、透明与颜色处理 | 生成主场景使用的平面反射颜色,能包含探针无法直接表示的本场景内容 |
| 主材质 | 输出表面颜色、法线与分类;场景写烘焙光,角色脸部写专用着色结果 | 形成后续光照的材质输入和已有 HDR 贡献 |
| 可见性与光照候选 | 分级深度用于遮挡判断;屏幕分区/世界网格缩小局部灯光候选;阴影与 AO 生成遮蔽 | 让后面的像素只处理相关灯光,并区分直接光遮挡与环境遮蔽 |
| 补光与合成 | 按材质类别消费输入,加入局部光、透明、雾和效果 | 得到当前帧最终待积累的颜色及运动/身份信息 |
| 历史与输出 | 运动定位旧像素,身份与颜色范围控制复用,再处理泛光、运动模糊与最终颜色 | 稳定当前画面,同时保留高亮的后续处理空间 |
2. 公共表面数据与材质分类
| 数据用途 | 本截帧的生成与编码 |
|---|---|
| 表面法线图:保存表面朝向,决定光照与遮蔽 | RGB 直接编码方向,RGB10A2 |
| 材质颜色图:为后续着色提供表面颜色 | RGBA8 sRGB;场景分支保存颜色,部分角色分支改作材质控制数据 |
| HDR 光照颜色图:存放已计算的亮度与颜色 | RGBA16F;材质阶段已包含烘焙光/角色着色等结果 |
| 运动矢量图:保存前后帧屏幕位移,定位历史像素 | 脸部已在材质扩展图的 RG 写压缩运动;后续另有运动与像素身份图供时序读取 |
| 附加材质参数图:控制表面如何接受后续光照 | RGB10A2在场景分支保存材质量、脸部分支复用为运动/标记;另有颜色图 alpha 控制量 |
| 材质类别/扩展标记图:选择处理分支 | 材质图通道与模板分类共同承载 |
| 相机深度与模板图:遮挡测试、空间位置重建与分类 | D32S8 |
法线由归一化方向映射为 0.5×N+0.5,消费端用
2×RGB-1
恢复方向。场景材质在写表面数据时建立模板分类,后续光照按类别解释通道:烘焙光照量与角色已着色颜色可以处于同一
HDR 目标,但不是同一种输入语义。
场景材质颜色和脸部控制量也可能复用相同附件;分类必须和通道一起保留。相机、镜像视图与光源的深度分别表示各自可见性,不能彼此替代。
3. 场景材质:压缩烘焙光与湿润表面
| 材质阶段:已有光照 | 材质阶段:表面颜色 | 后续完成后的画面 |
|---|---|---|
![]() |
![]() |
![]() |
观察 HIA 浮雕字、墙板凹处和吧台面。 左图已经具有明暗,但没有完整表面配色;中图保留红黄标牌、木地板与金属面分区;右图将这些数据与后续着色合成。前两图是同阶段的不同输出,说明光照量与表面颜色的分工;右图还包含后续灯光和后处理,不能当作单一效果开关实验。
以大厅通风口材质为例,其实际绑定包括底色 BC1 sRGB、法线 BC7 UNORM、材质遮罩 BC1 UNORM,以及 4096² BC7 UNORM 的压缩光照/天空遮蔽贴图。材质 UV 与烘焙光照 UV 分开:VS 对第二组 UV 使用每实例的缩放偏移,PS 再按该坐标读烘焙结果。
实例数据并非每 draw 一份独立矩阵。 代表 VS 用
实例编号+起始实例偏移 寻址,每实例跨 11 个
float4。其中位置变换使用前四组,法线使用另一组变换,切线朝向和负缩放符号独立处理,最后一组保存光照
UV 变换。这能说明实例常量的实际步长为 176
bytes;不能由此推出全引擎只有这一种实例格式。
法线采样先从贴图恢复切线空间方向:
1 | 法线XY = (2×贴图.R×贴图.A-1, 2×贴图.G-1) × 法线强度 |
本帧法线强度为 1。统一使用 R×A
的解包可以兼容不同的法线资源布局,不能因为纹理本次是 BC7 就跳过
alpha。基础材质遮罩的 G 被取反并限制到 0.99 后作为表面响应参数,R
则经独立强度控制;它们还会受到后续湿润处理影响,未把整套遮罩未经消费端证明地统一命名为
ORM。
本次压缩光照分支开关为 1。它把采样值限制到 0.9961,随后做有理式解码:
1 | u = min(压缩光照.RGB,0.9961) |
本帧光照强度为 1,天空附加颜色为零;贴图 alpha 仍经法线修正后保留在 HDR 附件 alpha。这个场景分支将光照量与材质颜色分开写,而角色脸部分支在 HDR 附件写已经着色的颜色;同一 RT0 的读取必须结合材质类别,不能全图统一当成 albedo 或完整最终颜色。
程序还包含空间湿润影响:从世界 xz
位置读湿润噪声,结合环境高度图的四次比较采样与位置高度范围,得到允许受影响的程度;表面朝上程度参与抑制竖直面。湿润量进一步改变颜色、表面响应参数,并在强度超过一定范围时把切线法线往
(0,0,1)
拉回,即压低细节起伏。仅从材质贴图本身看不出这些由世界环境控制的变化。
四个输出中,sRGB 颜色附件 alpha 打包三个布尔位;法线附件 alpha 固定为 0;材质扩展附件 alpha 在 0.67 与 1.01 间选取,写入 2-bit UNORM 后对应约 2/3 与 1。它是分类值而非透明度,解读时必须考虑附件量化。
证据:场景顶点程序、场景材质程序、本帧场景常量、本帧材质常量。
4. 局部灯光候选与列表构建
屏幕路径先计算灯光包围范围,选出与当前屏幕分区重叠的光,再按深度层和格子几何继续筛选。世界网格路径则按空间位置建立另一套灯光列表。两者都把“遍历全部灯光”变成“只读取当前格子的候选”,但寻址空间和表头布局不同,见下面的布局与筛选步骤。
局部灯光列表解决直接光的候选查找;烘焙光照贴图、天空遮蔽与环境反射探针提供另外的贡献。它们在同一场景中并存,不能把全部环境亮度归给屏幕空间计算。
屏幕分区、深度层与压缩表头
继续读取计算程序和本帧常量后,可以明确屏幕灯光组织的实际粒度:
| 项目 | 本帧数值 / 布局 | 实现意义 |
|---|---|---|
| 屏幕分区 | 64×64 像素 | 3432×1440 向上取整得到 54×23 个分区;最右/最下区域会裁到实际画面边界 |
| 每组线程 | 64 | 第一阶段分担灯光候选检查,后续每线程可对应一个深度层 |
| 深度层数 | 64 | 由本帧指数参数 6 得到 1<<6 |
| 每个屏幕分区的候选容量 | 128 | 共享内存中的候选数组有硬上限;超出的候选不会被该数组保留 |
| 灯光记录步长 | 156 bytes | 包含类型和用于相交测试的数据;不是只有位置/半径的 float4 |
| 空间包围数据步长 | 16 bytes | 分别读取屏幕范围与深度范围,先做粗筛 |
| 表头 | 每类每格 32 bits | 高 5 bits 存数量,低 27 bits 存列表起始偏移;写入数量限制到 31 |
| 两类灯光索引 | 分别以对应类型的起始位置为基数 | 列表保存类型内相对索引,消费端必须先还原所属类型,再读取灯光记录 |
处理流程不是一次原子追加就结束:
- 每个线程每轮检查一盏光,按 64 的步幅遍历输入列表;屏幕包围范围与当前 64×64 区域重叠才加入候选。
- 使用组内原子计数压紧候选,将候选数截到 128,补齐到 2 的幂并用 bitonic 排序网络按索引排序。排序保持后续类型/索引组织有序,不是按光照贡献大小挑选。
- 把每盏候选光的起止深度映射到层号;一盏灯光的两个 8-bit 层号占 16 bits,两个灯光范围可以放进一个 32-bit 共享记录。
- 按深度层计数并为全局索引列表预留空间,然后继续做灯光体积与格子几何的相交测试。
- 输出类型相对索引,并分别写两类的“数量+偏移”表头。消费者必须使用对应类型基数还原灯光索引。
深度层不是均匀间隔。本帧参数为近端 0.03、远端 5000、几何比 1.1,层边界可提炼为:
1 | 层边界(k) = 近端 + (远端-近端) * (1.1^k - 1) / (1.1^64 - 1) |
这些数值控制的是本次构建的深度划分,单位遵从捕获引擎,不能直接当成相机 UI 显示的米数。近处层更密,远处更稀,可在固定层数下覆盖很大的深度区间。
世界网格灯光路径有另一套结构:36-byte 的网格描述、360-byte 的灯光记录、8×8 线程组;组内通过 1/2/4/8/16/32 步长的前缀和计算输出偏移,再由一个线程向全局列表分配整组空间。它的格子表头采用高 8 bits 计数、低位偏移的组合,而非屏幕列表的高 5 bits 计数。两者的 buffer/表头格式不能共用一个未经区分的解码器。
证据:屏幕灯光列表构建、本帧屏幕列表参数、世界网格灯光筛选。
5. 阴影缓存、屏幕解析与局部遮蔽
局部光阴影按子区块放入图集,主相机相关的阴影视图则存入数组。阴影代理可以使用不同于可见材质的几何;角色脸部还消费附加阴影深度,处理主场景阴影之外的遮挡需求。
屏幕解析先由相机深度恢复可见表面位置,再投影到对应阴影视图进行比较,将“光源能否看见这里”转换成当前像素的受光比例,随后滤波。对象级分类和解析接在公共结果上,使局部角色遮挡可以拥有独立规则;具体接入见 角色阴影与胶囊遮蔽。
屏幕环境遮蔽具有独立的生成和过滤链,半分辨率 R8 遮蔽历史参与后续消费;分级深度为屏幕查询提供输入。角色胶囊路径还使用简化空间几何,和只沿可见深度搜索的屏幕遮蔽分开。
当前已确认它们的输入输出与接入顺序,未完整还原屏幕 AO 的方向采样规则与每个历史权重,不能仅凭程序名称指定某个库版本。
6. 平面反射与环境探针
平面反射从镜像视点重新处理场景几何、材质、照明、透明与颜色后处理,生成主视图使用的离屏颜色。它有自己的深度与可见性,因此反射数据的生产本身是一条场景渲染路径。
场景同时使用压缩 HDR 立方体反射探针。镜像视图与环境探针是不同来源:前者依赖额外视点的几何与着色结果,后者以预存空间方向颜色参与反射。两种来源在各材质中的完整选择和混合规则尚未全部拆解。
7. 天空、雾与分域颜色变换
天空查找表为环境颜色计算提供预计算数据;角色、场景与通用颜色变换又各有查找表。因此角色在进入最终整帧合成之前,就可以采用不同于场景的颜色变换,眼睛路径的具体查表公式见 角色眼睛分析。
雾的可见链路包含生成屏幕颜色与合成。当前证据还未把其内部介质存储完整还原,不能将它直接套成另外两者已确认的三维体积积分方法。
8. 时序融合:颜色与像素身份共同验证历史
运动图的 RG 保存压缩屏幕位移,B 保存历史身份标记,附加覆盖标记控制部分采样和旁路。颜色历史采用 HDR RGB,身份历史独立保存在 R8。身份用于重投影匹配,尚未证明它等同于 CPU 逻辑对象编号。
1 | q = 编码运动.RG - 127/255 |
完整处理有以下先后关系:
- 从中心和四个对角深度候选中择近,沿该表面的运动寻找历史;中心覆盖标记和标记的屏幕导数影响是否去除当前采样偏移,以及是否旁路历史。
- 点采样历史身份,与当前身份比较。差值绝对值大于 0.1 时直接输出当前颜色及身份,停止使用旧颜色。
- 身份允许时,对旧 HDR 颜色取双线性样本;当前颜色读取中心和四个半 texel 对角位置,本帧使用 0.6 的锐化参数。
- 按最大颜色通道把 RGB 压入较小范围;用对角邻居的最小/最大值与亮度差构造扩张区间,沿区间中心方向裁剪旧颜色。
- 按运动量把历史基础权重从约 0.95 降至约 0.70,混合后反变换;最后由中心标记进一步混向当前颜色。
- 同步输出新 HDR 颜色和当前身份,作为下一次历史。
因此身份拒绝处理的是“是否仍对应当前表面”,颜色裁剪处理的是“旧值是否仍适合当前邻域”,运动权重处理的是“积累应有多强”。三者不能互相代替。
证据:时序融合程序、同截帧时序公式核对。
9. 泛光、运动模糊与最终输出
主要历史融合在最终颜色处理之前完成,后面继续泛光、过滤与运动模糊。角色/场景专用颜色查找表可以更早参与材质着色,因此最终颜色变换不是全部调色逻辑的唯一位置。
10. 分析边界与证据
烘焙光、灯光列表、部分场景材质、镜像视图与主要时序规则已有直接证据。全部局部灯光消费分支、屏幕 AO 内核、雾内部存储、其他场景材质变体与跨帧缓存更新策略仍未完整还原。
场景绑定附录 保留原始管线状态,资源语义索引 对照各资源用途;各算法段落的程序与常量链接可用于重新核对。


