《刺客信条:影》的渲染

Rendering Assassin's Creed Shadows


Anvil 引擎概述与历史演进

Anvil 引擎的诞生与定位

  • Anvil 引擎 诞生于 2004 年(开发阶段),随 《刺客信条 1》 于 2007 年正式面世
  • 引擎设计核心目标:
    • 支撑 大型系统化开放世界(Large Systemic Open Worlds)
    • 远距离渲染(Long-range Rendering)
    • 系统化游戏玩法(Systemic Gameplay)
  • 除《刺客信条》系列外,Anvil 还支撑了多个育碧大型 IP:《幽灵行动》(Ghost Recon)《荣耀战魂》(For Honor)《彩虹六号:围攻》(Rainbow Six Siege)
  • 这些游戏类型跨度极大——竞技 FPS、多人对战、开放世界动作 RPG——对同一引擎的适配提出了巨大挑战

引擎分叉(Fork)问题与统一化改革

  • 历史问题:引擎大量分叉

    • 最初的刺客信条引擎名为 Scimitar ,后来分叉出 Blacksmith (主要用于《彩虹六号》和 Silex)以及 Silex (主要用于《幽灵行动》开放世界)
    • 育碧内部曾同时存在大量引擎:Anvil、Snowdrop、Dunia、Voyager、UbiArt 等,每个引擎又有多个分叉版本
    • 这导致了 开发工作的大量重复(Multiplication of Effort) ——同一个功能或系统在多个引擎中被反复实现
  • 关键认知转变:

    • 大型系统的开发周期长达 数年 ,其代码在代码库中的生命周期可达 十年之久
    • 完整重写大型系统的机会非常有限
    • 重复开发使育碧在竞争力上 处于劣势
  • 当前解决方案:Monorepo(单一代码仓库)模式

    • Anvil 现在作为 跨多款游戏、多种类型、多个品牌的共享引擎 运作
    • 所有团队在 一个统一的代码库(Monorepo) 中协作
    • 技术团队和制作团队分布在全球各地,共同开发

《刺客信条:影》的渲染目标与起点

项目定位与前作基准

  • 前作 《刺客信条:英灵殿》(Valhalla) 是本项目启动时的 开放世界 AC RPG 基准线
  • 关键区别:
    • 《英灵殿》是一款 跨世代(Cross-gen) 游戏,需要同时兼容上一代和当代主机
    • 《影》被定位为 首款真正的次世代(Next-gen)刺客信条游戏 ——不再需要兼容旧世代硬件

《英灵殿》的可扩展性局限

  • 《英灵殿》在 画质模式(Quality Mode)性能模式(Performance Mode) 下画面差异很小,可扩展性有限
  • 主要的可扩展性手段几乎仅依赖 渲染分辨率(Render Resolution) 的调整
  • 具体数据:在 Xbox Series X 上以 4K 原生分辨率30 FPS 运行时,GPU 占用仅约 20 毫秒出头 ——这意味着 GPU 的性能预算远未被充分利用

《影》的核心渲染目标

  • 基于对前作的分析,团队明确了核心方向:将可扩展性(Scalability)推向全新高度
  • 作为纯次世代游戏,可以放开手脚利用新硬件特性,在画质和性能之间实现更有意义的差异化

要点总结

维度关键信息
引擎Anvil,2004 年起步,支撑育碧多个核心 IP
架构改革从多引擎多分叉 → Monorepo 单一代码库共享引擎
前作基准《英灵殿》跨世代,GPU 利用率低,可扩展性有限
本作定位首款纯次世代 AC,目标:大幅提升可扩展性与渲染质量

《刺客信条:影》的项目规模与渲染管线


项目规模与复杂度

《影》的功能范围

  • 使用 Anvil 引擎 构建
  • 16×16 公里的开放世界 ,支持 昼夜变化(Time of Day)
  • 以上这些在《英灵殿》中已经实现,但《影》在此基础上新增了:
    • 大规模破坏系统(Massive Destruction)
    • 光线追踪(Ray Tracing)
    • 虚拟几何体(Virtual Geometry)
    • 系统化天气(Systemic Weather)
    • 四季变化(Seasons)
  • 演讲者坦言:项目初期看到这份需求清单时"表情和大家一样震惊",但最终确实成功交付了

复杂度的直观展示

  • 游戏场景同时叠加了 昼夜天气状态四季 三个维度的变化
  • 同一场景在不同时间点、不同天气、不同季节(含冬季积雪)下呈现截然不同的视觉效果

平台与模式配置

  • 纯次世代(Gen 5 Only) 游戏,支持三款当代主机
  • 提供三种显示模式:
    • 性能模式(Performance Mode)
    • 平衡模式(Balanced Mode)
    • 画质模式(Quality Mode)
  • 各模式有不同的 目标分辨率
  • 关键决策: 团队在开发初期就决定,光线追踪(Ray Tracing)优先用于画质模式

Anvil 引擎的远距离渲染架构

世界分区与流式加载

  • Anvil 引擎 从底层就为远距离渲染(Long-range Rendering)而设计
  • 世界被划分为 单元格(Cells) ,支持 多用户协同编辑
  • 数据组织为 流式网格层(Streaming Grid Layers) ,网格定义完全 数据驱动(Data-driven) ——不同游戏可以有不同的网格配置

LOD 网格层级体系

整个渲染距离被划分为多个层级,从近到远依次为:

层级名称覆盖范围内容说明
近距离网格(Short-range Grid)LOD 网格最近距离大量小型道具(Props),靠近玩家时显示,远离后可以消失(对整体画面和游戏性影响不大)
主网格(Main Grid)LOD 网格中等距离大部分游戏资产 都在此层级
远距离网格(Long-range Grid)LOD 网格较远距离大型资产或 兴趣点(Point of Interest) ,需要在更远距离保持可见
伪实体网格(Fake Entity Grid)简化资产最远约 4 公里包含 抽稀资产(Decimated Assets)聚合资产(Aggregated Assets)
点云(Point Clouds)批量冒名顶替者渲染最远约 8 公里大规模四边形冒名顶替者渲染器(Mass Quad Renderer) ,主要用于远距离树木等
地形远景(Terrain Vista)烘焙地形8 公里以上仅剩地形本身,大量细节被 烘焙(Baked) 进地形纹理

LOD 选择器与加载网格

  • 加载网格(Loading Grids) 可以在 实体级别(Entity Level) 指定
  • 距离切换由 LOD 选择器(LOD Selectors) 驱动
  • LOD 选择器必须与加载网格 匹配(Matching) ——如果设置不一致,可能导致物体在错误的距离消失

点云渲染器效果展示

  • 点云渲染器 本质上是一个 极快的批量四边形渲染器(Lightning-fast Quad Renderer)
  • 用于在最远 8 公里 处渲染树木等植被的 冒名顶替者(Imposters)
  • 开启前后对比效果显著——远处山坡、森林的覆盖密度差异巨大
  • 调试视图显示:场景中冒名顶替者的数量 极为庞大 ,遍布整个视野

GPU 驱动管线的演进

历史:从《刺客信条:大革命》开始

  • GPU 驱动管线(GPU-driven Pipeline)《刺客信条:大革命》(Unity,2014 年) 起就是 Anvil 引擎的 基石(Cornerstone)
  • 此后经历了多款游戏和多次迭代

第一代:Batch Renderer(批次渲染器)

  • 出现于 《刺客信条:大革命》

  • 基于 DX11 级别 API 的 GPU 驱动管线

  • 核心目标: 减少昂贵的 DX11 Draw Call 开销

  • 技术手段:

    • 使用 Multi-Draw Indirect 进行剔除和渲染
    • 引入 簇级网格(Cluster Meshes) 的精细剔除
    • 实现了 实例级(Instance)、簇级(Cluster)、三角形级(Triangle) 的多层剔除
  • 局限性:

    • 仍有 大量工作在 CPU 端 完成
    • 不支持无绑定纹理(Bindless Textures) ——严重限制了批处理能力
    • 仅能做到 逐材质批处理(Per-material Batching)
    • 不支持计算着色器的某些操作
    • CPU 端的处理会 延迟网格渲染的启动时机

第二代:GPU Instance Renderer(GPU 实例渲染器,简称 GPU IR)

  • 专为 DX12 级别 API 设计的全新管线
  • 关键改进:
特性Batch Renderer(旧)GPU IR(新)
API 级别DX11DX12
绑定模式需要绑定纹理完全无绑定(Fully Bindless)
批处理粒度逐材质(Per-material)逐着色器(Per-shader)
批处理时机运行时加载时(Load Time) 预计算
剔除能力百万级以下设计为 每帧剔除数百万实例
CPU/GPU 分工CPU 占比大大量步骤从 CPU 迁移到 GPU

Database 概念

  • GPU IR 依赖一个称为 Database 的核心结构
  • Database 不是传统意义上的数据库 ,而是一个 CPU 与 GPU 之间共享数据结构的容器(Container)
  • 它充当 CPU 和 GPU 之间的桥梁,使得 GPU 端可以高效访问渲染所需的所有实例、材质、几何数据

要点总结

维度关键信息
项目规模16×16km 开放世界 + 昼夜 + 天气 + 四季 + 破坏 + 光追 + 虚拟几何体
远距离渲染6 层 LOD 体系,从近距道具到 8km+ 地形远景,完全数据驱动
点云渲染极速四边形渲染器,8km 内渲染海量树木冒名顶替者
GPU 管线演进DX11 Batch Renderer → DX12 GPU Instance Renderer(全无绑定、逐着色器批处理、加载时预处理)
核心抽象Database ——CPU/GPU 共享数据结构容器,驱动整个 GPU 管线

GPU 数据库(GPU Database)系统


设计理念与核心概念

数据导向设计(Data-Oriented Design)

  • GPU Database 遵循 数据导向设计(Data-Oriented Design) 原则,配合引用机制(Referencing Mechanism)
  • 演讲者将其比喻为一个 "超级结构化缓冲区(Super-Structured Buffer)" ——本质上就是一块高度组织化的 GPU 可见内存

与 SIG(Shader Input Groups)的集成

  • Anvil 引擎内部有一套自研的着色器绑定编译器,称为 SIG(Shader Input Groups)
  • SIG 负责 自动生成 所有 getter/setter 函数以及绑定代码
  • 团队 扩展了 SIG 语言 ,使其能够 声明数据库表(Tables)
  • 开发者无需手写访问接口——SIG 自动生成 C++ 端和 HLSL 端完全一致的访问代码

数据库类比

  • 之所以称为"数据库",是因为使用了 数据库的类比方式 来组织数据
  • 核心目的:在 CPU 和 GPU 之间共享完整的场景描述(Full Scene Description)
  • 一个 行(Row) 本质上等价于一个 指向对象的指针 ——例如 Row<MyObject> 就相当于 MyObject*

表声明与跨语言访问

声明方式

  • 在 SIG 格式中声明表结构(顶层定义)
  • 编译后同时生成 C++HLSL 两端的访问代码
  • 所有接口(getter、setter 等)全部自动生成 ,操作非常简便

关系系统(Relations)

一对一关系(One-to-One Relation)

  • 数据库中的 一对一关系 本质等价于一个 指针(Pointer)
  • 一张表中的某一行指向另一张表中的某一行

一对多关系(One-to-Many Relation)

  • 一对多关系 是一对一的扩展——相当于 一个带有大小(size)的指针
  • 可以从一个父对象指向 多个子对象
  • 这使得系统能够构建出 类似 C++ 对象图的完整网格关系与属性描述
    • 例如:一个 Mesh 实例拥有多个 SubMesh,每个 SubMesh 引用不同的 Material 等

CPU 到 GPU 的数据同步模式

GPU Database 在 CPU 和 GPU 上各有 不同的表实例(Table Instances) ,支持多种数据传播模式:

同步模式机制描述适用场景
Copy Mode(完整拷贝)最简单的模式,将 CPU 端整张表 完整复制 到 GPU 端的 Byte Address Buffer数据量较小、变化频繁的表
Dirty Row / Dirty Pages(脏行/脏页更新)维护一个 脏标记掩码(Dirty Mask) ,仅将标记为"脏"的行或页 增量复制 到目标表数据量较大但每帧仅少量变化的表
CPU 端仅存脏行(Flush Mode)对于 极大的表 ,CPU 端 不完整存储 全部数据(避免内存饱和),仅暂存脏行,刷新(Flush)后即释放超大规模表,CPU 内存受限场景

关键设计要点

  • 数据流向 通常是 CPU → GPU ,但架构本身支持更灵活的方向
  • GPU 端的表结构与 CPU 端 并非完全相同 ——GPU 端会 针对性优化 ,移除不需要的参数,保留渲染所需的最小数据集

要点总结

维度关键信息
核心思想用数据库范式在 GPU 上构建 结构化的完整场景描述
代码生成通过扩展 SIG 编译器 自动生成 C++ 和 HLSL 双端访问代码
关系支持一对一(指针)、一对多(带 size 的指针),可描述复杂的网格/材质层级
同步策略三种模式:完整拷贝、脏行/脏页增量更新、仅存脏行刷新
优化原则GPU 端表结构独立优化,不存冗余数据

CalMesh 表结构、GPU 驱动管线与微多边形几何管线


CalMesh 数据模型与表结构

CalMesh 的 LOD 体系

  • 每个 CalMesh 最多支持 5 个 LOD 级别
  • 每个 LOD 包含:
    • 两个 LOD 距离 ——一个用于 主视图(Main View) ,一个用于 阴影(Shadows)
    • 两个 LOD 自定义参数 ,用于调整阴影 LOD 距离
  • 几何体与 PSO(Pipeline State Object)的关联子网格(Sub-mesh)级别 通过 Batch Hash 实现
  • 关键约束:每个 PSO 只对应一个 Batch ,因此批次的去重(Deduplicate)极其简单

SIG 中的表声明

  • 所有上述结构都通过 SIG 语言声明为表(Tables)
  • 视觉上非常接近 结构化缓冲区(Structured Buffer) 的写法
  • 表与表之间通过 Row(行引用)Range(范围引用) 关系链接——对应前文提到的一对一和一对多关系

世界组织:核心树与叶节点

层级剔除结构

  • 整个游戏世界被组织为一棵 核心树(Core Tree)
  • 为了达到良好的 剔除(Culling)性能 ,依赖层级化结构:
    • 实体组(Entity Groups)叶节点(Leaf Nodes)
  • 叶节点本质上是一组实例(Group of Instances)
    • 空间上彼此接近的实例 聚合到同一叶节点中
    • 目的:最小化包围体(Bounding Volume) ,使 CPU 端的剔除更高效

表的生命周期(代码层面)

整个流程分为四步:

  1. 声明 ——分别声明 CPU 表和 GPU 表(二者结构可以不同)
  2. 填充 ——在 CalMesh 表中创建条目,设置各种属性
  3. 同步 ——触发表的 GPU 更新(底层使用前文描述的 Copy / Dirty Row / Flush 等策略)
  4. GPU 端使用 ——在着色器中获取数据并使用

布局注解:SoA 与 AoS 的灵活选择

  • SIG 语言支持通过 注解(Annotations) 指定表的内存布局:
    • 结构体数组(Array of Structures, AoS)
    • 数组的结构体(Structure of Arrays, SoA)
    • 甚至可以 混合搭配(Mix and Match)
  • 这确保了 最大化缓存效率(Cache Efficiency) ——根据实际访问模式选择最优布局
  • 演讲者总结:GPU Database 本质上就是一个 "我一直希望图形 API 能原生提供的超级结构化缓冲区"

完整 GPU 驱动管线流程

三阶段剔除架构

整个管线分为 CPU 阶段GPU 两阶段

阶段执行位置具体操作
粗粒度剔除(Coarse Culling)CPU叶节点(Leaf Nodes) 进行剔除——即按实例组为单位快速排除
帧级剔除(Frame Culling)GPU对通过 CPU 剔除的实例,针对 所有渲染 Pass 的所有视锥体 统一执行剔除;同时处理 LOD 选择与混合(LOD Selection & Blending)
逐 Pass 剔除(Per-Pass Culling)GPU执行 特定于 Pass 的视锥剔除(Frustum Culling)遮挡剔除(Occlusion Culling) ;例如太阳阴影会 按级联(Per Cascade) 进行视锥剔除

逐 Pass 剔除的额外职责

  • 准备实例数据 ,供顶点着色器和像素着色器访问:
    • 几何数据(统一顶点缓冲区中的偏移)
    • 材质数据和常量(统一材质缓冲区中的偏移)
  • 因为引擎使用 统一缓冲区(Unified Buffers) 存储顶点和材质数据,所以必须维护一套 描述信息 来定位每个实例的数据位置

可选的集群级剔除

  • 在最终光栅化之前,支持 可选的(Optional) 进一步剔除:
    • Cluster Culling(集群剔除)
    • Triangle Culling(三角形背面剔除)

微多边形几何管线(Micro-Polygon Geometry Pipeline)

技术来源

  • 基于 Brian Karis 在 2021 年发表的 Nanite 技术
  • 本质是 离散集群网格管线(Discrete Cluster Mesh Pipeline) 的进一步演化

核心机制

特性说明
集群层级结构(Cluster Hierarchy)网格由集群层级组成,支持 连续 LOD(Continuous Level of Detail)
集群流式加载(Cluster Streaming)基于可见性 逐集群单独流式加载
混合光栅化(Hybrid Rasterization)多边形根据其屏幕大小选择 硬件光栅化软件光栅化
使用场景用于 G-Buffer 渲染阴影光栅化
内存效率相同几何体在此管线中占用的内存约为 GPU 实例渲染管线的一半

与业界其他实现的共同点

  • 使用 Metis 库 进行 集群分区(Cluster Partitioning)
  • 根据三角形大小选择 Mesh Shader软件光栅化
  • 采用 两趟层级缓冲遮挡剔除系统(Two-Pass Hierarchical Buffer Occlusion System)
  • Visibility Buffer 渲染不同材质到 G-Buffer
  • 集群大小为 128 个三角形 (相比旧版 GPU 驱动管线如《刺客信条:大革命》使用的 64 个三角形,翻倍)

与业界其他实现的差异点

差异维度《影》的做法
网格简化(Mesh Simplification)使用 SimpliGol 生成集群组简化——效果良好
自定义着色器支持支持 用户自定义着色器代码 ,通过 手动 API 接入 Shader Graph
Bindless 架构管线 完全无绑定(Fully Bindless) ,与 GPU 实例渲染器保持一致

要点总结

维度关键信息
CalMesh 模型最多 5 LOD,每 LOD 双距离(主视图+阴影),PSO 通过 Batch Hash 在 Sub-mesh 级别关联
世界组织核心树 → 实体组 → 叶节点(空间聚合的实例组),CPU 端粗粒度剔除
GPU 剔除帧级(全 Pass 统一)→ 逐 Pass(视锥+遮挡)→ 可选集群/三角形剔除
微多边形管线基于 Nanite 思路,连续 LOD、逐集群流式、混合光栅化、128 三角形/集群、内存减半
统一设计GPU Database + Bindless 架构贯穿两套管线,SIG 自动生成双端代码

微多边形渲染统计与全局光照管线


软件光栅化优化:坐标翻转

X/Y 坐标交换技巧

  • 软件光栅化算法本质上执行的是 扫描线算法(Scanline Algorithm) 来逐行填充三角形
  • 通常扫描线是 水平方向 执行的
  • 问题: 当遇到 垂直方向的三角形 时,水平扫描线的分支一致性(Branch Coherency)和负载均衡会变差
  • 解决方案: 根据三角形的朝向配置,动态交换 X 和 Y 坐标 ——将垂直三角形"翻转"为水平处理
  • 效果:提升分支一致性工作负载均衡(Workload Balancing)

微多边形与 GPU 实例渲染器的分工

当前支持范围

渲染器支持的几何类型典型用途
微多边形管线(Micro-polygon)仅支持 静态不透明几何体(Static Opaque Geometry)城市建筑、静态几何
GPU 实例渲染器(GPU Instance Renderer)支持 Alpha Test大规模植被渲染(树木等)
  • 目前微多边形管线 不支持 Alpha Test ,但这是未来计划要做的功能

城市场景统计数据

指标微多边形管线GPU 实例渲染器
实例数~28,000~9,000(跨所有 Pass)
渲染三角形数~3,400 万~200 万
软件光栅化比例90% 的三角形由软件光栅化处理
  • 软件光栅化比例 取决于
    • 几何体本身的特性
    • 曲面细分级别(Tessellation Level)
    • 渲染分辨率 ——分辨率越低,每个多边形覆盖的像素越少,更适合软件光栅化

森林场景统计数据(反转场景)

指标数值
剔除前实例数~300 万
剔除后渲染实例数~30,000
剔除前三角形总数15 亿(1.5 Billion)
最终渲染三角形数~700 万
  • 森林场景中 微多边形管线退居次要地位 ——仅渲染少量建筑和岩石
  • GPU 实例渲染器承担主要负荷 ——大量树木植被的渲染
  • 剔除效率极高:从 300 万实例中仅保留 3 万,从 15 亿三角形中仅渲染 700 万

关键结论

  • 由于微多边形管线主要处理建筑等静态不透明几何,而森林场景的主要负载由 GPU 实例渲染器承担,因此 没有迫切压力 在微多边形管线中支持 Alpha Test
  • 但未来 一定会加入 Alpha Test 支持

全局光照(Global Illumination)管线

GI 技术的历史演进

作品技术方案关键特性
《刺客信条:大革命》(AC Unity)体积化开放世界 GI(Volumetric Open World GI)GPU 上使用 光线束(Ray Bundles) 烘焙;均匀 Mipmap 辐射度体积;Mipmap 作为远距离 LOD;不支持动态昼夜 ,使用 4 个固定静态氛围伪装
《刺客信条:枭雄》(AC Syndicate)在 Unity 基础上改进新增 动态昼夜支持 ——在两个固定 GI 关键帧之间 混合插值(Blending)
《刺客信条:起源》(AC Origins)稀疏化(Sparse) 体积 GI适配 16×16 公里超大开放世界
《刺客信条:影》(AC Shadows)可扩展 GI 管线 + 光线追踪 GI支持四季变化;从全烘焙到全光追的完整光谱

推荐参考:Josh Opson 关于 《战神》(God of War) 中辐照度缓存(Irradiance Caching)的演讲,其技术基础源自 AC Unity 的工作

规模化挑战:为何需要新方案

  • 从 Unity/Syndicate 的数据 朴素外推 到 16×16 公里开放世界:
    • 预计 GI 数据量将达到 ~500 GB
  • 若再叠加《影》的 四季系统
    • 数据量飙升至接近 2 TB
    • 烘焙时间超过 600 天
  • 即便拥有无限的云计算资源(Google Cloud、Azure 等),蓝光光盘容量也无法容纳 这么多数据
  • 结论:必须从根本上改变技术方案

《影》的 GI 管线设计:可扩展光谱

设计原则

  • 从一开始就以 可扩展性(Scalable) 为目标
  • 光线追踪代价高昂,不希望为了 GI 牺牲游戏的其他部分——尤其是在 60 FPS 模式
  • 考虑到 硬件多样性 ,给予玩家更多选择——实践证明这种做法 广受欢迎

GI 质量光谱

管线设计为一个从低到高的 连续光谱

完全烘焙(Fully Baked)          ←————————————————→          完全光追(Fully Ray-Traced)
  漫反射 + 镜面反射                                           漫反射 + 镜面反射
模式漫反射 GI镜面反射 GI说明
全烘焙烘焙烘焙最低开销
混合可选光追/烘焙可选光追/烘焙灵活配置
全光追光线追踪光线追踪最高质量

光线追踪实现方式

  • 硬件光线追踪(Hardware Ray Tracing) ——使用 GPU 的 RT 核心
  • 软件光线追踪(Software Ray Tracing) ——使用 计算着色器(Compute Shaders) 实现

特殊场景:藏身处(Hideout)

  • 藏身处是一个 完全动态的类《模拟城市》建造系统
  • 建筑物完全由玩家放置,无法预先烘焙
  • 必须使用光线追踪 GI ——否则将完全没有全局光照

要点总结

维度关键信息
软件光栅化优化根据三角形朝向交换 X/Y,提升分支一致性
城市场景微多边形为主(2.8 万实例 / 3400 万三角形),90% 软件光栅化
森林场景GPU 实例渲染器为主,剔除比例极高(15 亿 → 700 万三角形)
GI 历史Unity(均匀体积)→ Syndicate(动态昼夜)→ Origins(稀疏化)→ Shadows(光追光谱)
规模化瓶颈16km 世界 + 四季 = ~2TB 烘焙数据 + 600 天烘焙时间,不可行
《影》GI 方案可扩展光谱:从全烘焙到全光追,支持硬件/软件两种光追实现

烘焙 GI 的规模化优化策略


从 GPU 烘焙迁移到 CPU 烘焙

迁移动机

团队在从《起源》时代开始,将 GI 烘焙后端 从 GPU 转移到 CPU ,原因包括:

原因说明
VRAM 限制GPU 烘焙需要大量显存,内存悬崖(Memory Cliff) 问题严重,尤其在《起源》时期
构建农场一致性CPU 端不受 驱动差异GPU 型号多样性 影响,结果更稳定
输入确定性使烘焙输入 完全确定(Deterministic) ——能精确知道哪些需要烘焙、哪些不需要
分发更快本地机器执行的工作更少,更容易分发到构建农场

密度图与稀疏探针放置

密度图(Density Map)

  • 核心洞察: 在烘焙 GI 方案中,纹素/探针密度决定了细节质量 ——但密度 不需要在整个世界中均匀分布
  • 解决方案: 使用 密度图(Density Map) 手动绘制 GI 分辨率
    • 确保 最重要的区域 获得最高密度
    • 只有 少数区域 (主要城市,图中蓝色区域)达到与旧作《大革命》相同的 50 厘米轴距 分辨率
    • 尽管如此,这些高密度区域的 面积仍然大于 前几代游戏的整个地图
  • 世界其余部分使用 低得多的密度 ,大幅节省存储空间

稀疏八叉树探针分布(Sparse Octree)

密度图之后数据仍然过大,进一步优化:

  • 探针分布在 稀疏八叉树(Sparse Octree)
  • 八叉树节点 仅在包含表面(Surface)时才细分
  • 丢弃位于几何体内部的探针 ,进一步节省空间
  • 最终结果:探针数量 仅为均匀分布的约 10%

昼夜与四季支持

昼夜变化:关键帧方案

  • 存储 11 个关键帧(Key Frames)
    • 1 个 用于 局部光源(Local Lights)
    • 10 个 用于 太阳不同位置
  • 关键帧数量 完全由数据驱动 ,可根据需求增减
  • 数据按 太阳光、局部光、天空光 分开存储,使用 YCoCg 格式
    • Y(亮度/Luma) :具有方向性,以 球谐函数(Spherical Harmonics) 存储
    • Co/Cg(色度/Chroma) :标量值

四季变化:最小化烘焙开销

目标:即使需要多次烘焙 GI,也要将 数据量额外开销降到最低

团队做出两个 "明知有误但实际可用" 的近似假设:

假设说明合理性
春季 ≈ 夏季在间接光照层面视为同一季节BRDF 几乎一致,季节视觉差异主要来自 资产替换、雾和天气 ,而非光照本身
Luma 跨季节不变亮度(Y 通道)仅存储一份,色度(Co/Cg)按季节分别存储这是明确的近似——当几何体在不同季节间发生显著变化时(如植被出现/消失),亮度与色度可能不匹配

处理不匹配问题的策略:

  • 大多数受季节强烈影响的是 植被 ,影响可控
  • 有问题的几何体可以由 技术美术(Tech Artist)标记并排除出烘焙
  • 实际项目中 问题很少

运行时:稀疏数据到级联体积的插入

运行时管线流程

稀疏体素数据 → 解压(Decompression)→ 插入到级联3D体积(Cascaded 3D Volumes)
  • 运行时使用 均匀采样的级联体积(Uniform Cascades)
  • 稀疏数据需经过 解压步骤 ,转换为非稀疏格式后再插入级联

混合策略(避免 Popping)

混合类型说明
跨级联混合(Cross-Cascade Blending)相邻级联之间平滑过渡
原地 GI Block LOD 混合(In-place GI Block LOD Blending)当新的 GI Block LOD 加载时,在原位置进行混合,避免弹出伪影(Popping)

与前作对比

维度《大革命》(AC Unity)《影》(AC Shadows)
GI 格式离散 GI 网格(Discrete GI Grid)稀疏 GI Block 插入 级联 GI 体积
LOD 机制Mipmap 按视距离散加载(类似 2D 纹理流式加载,但对象是 3D 体积)连续的细节层次(Continuous Level of Detail)
视觉效果效果已经很好过渡更加平滑自然

最终数据量对比

方案GI 数据量
朴素均匀方案(类似《大革命》方式外推到 16×16km)~2 TB
《影》最终方案(密度图 + 稀疏八叉树 + 季节压缩)~9 GB
  • 压缩比约 220 倍 ——从完全不可行的 2TB 降低到可接受的 9GB
  • 主要贡献来自 密度图稀疏网格

效果评价

  • 团队 并未追求完全精确(Full Exactitude/Accuracy) ——这是一个 近似方案
  • 但最终效果 可信且合理(Plausible and Believable)
  • 考虑到数据量仅 9GB 却覆盖 16×16 公里 + 昼夜 + 四季,团队 对结果相当满意

要点总结

维度关键信息
烘焙后端GPU → CPU ,解决 VRAM、确定性、一致性问题
空间优化密度图 控制分辨率分布 + 稀疏八叉树 仅 10% 探针量
时间维度11 个昼夜关键帧;春≈夏,Luma 跨季节共享,Chroma 按季节存储
运行时稀疏数据解压后插入 级联均匀体积 ,跨级联 + LOD 混合
数据量从理论 2TB 压缩至 9GB ,效果可信

镜面反射、光线追踪抽象层与混合光追 GI


镜面反射(Specular Reflections)管线

反射层级(按优先级排序)

优先级技术说明
1(最高)屏幕空间反射(SSR)首选方案
2可重定位的 GBuffer 立方体贴图(Relatable GBuffer Cubemaps)预烘焙的局部立方体贴图
3(兜底)动态立方体贴图(Dynamic Cubemap)在玩家位置渲染,作为全局兜底的"区域立方体贴图"

GBuffer 立方体贴图(GBuffer Cubemaps)

存储内容

  • 每张立方体贴图存储完整的 GBuffer 属性
    • Albedo(反照率)
    • Normal(法线)
    • Depth(深度)
  • 运行时 动态读取并重新光照 ,而非存储预计算的最终颜色

烘焙阴影的巧妙编码

  • 阴影信息也被烘焙进立方体贴图
  • 存储方式:在 8 位纹理 中存储 8 个关键帧 ——每个关键帧占 1 bit
  • 运行时:
    1. 选择与当前昼夜时间 最近的两个关键帧
    2. 在两者之间 插值混合(Blend)
  • 效果 出奇地好 ——由于立方体贴图分辨率本身不高,即使没有过滤(No Filtering)也看不出问题

季节支持:变体状态(Variation States)

  • 使用 变体状态(Variation States) 系统——一种数据驱动的、实体级别的游戏特定逻辑机制
  • 每张立方体贴图最多存储 3 个变体 (回顾前文:春季 ≈ 夏季,因此只需 3 个季节变体)
  • 并非所有立方体贴图都有变体——部分室内场景不需要季节变化

规模数据

指标数值
总立方体贴图数量16,000 张(不含变体)
变体覆盖率大多数室外立方体贴图都有变体

动态立方体贴图

  • 设计目标:渲染成本极低
  • 渲染内容:伪实体(Fake Entities) ——即抽稀/聚合的 LOD 资产
  • 阴影使用 更低分辨率
  • 对比展示:动态立方体贴图与同位置的局部烘焙立方体贴图 效果非常接近

光线追踪抽象层

设计背景与动机

  • 光线追踪是《影》的 重大开发投入
  • 受到 育碧 Snowdrop 引擎团队 工作的启发
  • 关键决策:团队 不确定 最终哪种光追方案最优,因此选择 保持所有选项开放
  • 目标:实现 Inline(内联)与 Non-inline(非内联) 以及 硬件与软件 光线追踪的 完全抽象

Fusion 硬件抽象层

  • 光线追踪技术栈被抽象到一个名为 Fusion 的硬件抽象层之下
  • Fusion 在 育碧内部跨多个引擎共享
  • 采用 内源开发模式(Insourcing Model)
    • 代码托管在内部 GitLab
    • 任何团队都可以贡献改进,惠及育碧多个项目

统一光线追踪 API

抽象维度包括:

抽象维度说明
平台特定 API统一不同平台的光追 API(常规做法)
硬件 vs 软件光追同一接口同时支持硬件光追和软件光追
Inline vs Non-inline同一接口同时支持内联和非内联模式

回调接口设计

光追循环(Ray Tracing Loop)
    ├── Hit Callback(命中回调)
    ├── Any Hit Callback(任意命中回调)
    └── Miss Callback(未命中回调)
  • Inline 模式: 根据命中状态(Hit/Any Hit/Miss),直接调用对应的回调函数
    • 用户代码负责编写回调,使其 行为等同于 Non-inline 模式中的各个着色器阶段
  • Non-inline 模式: 在对应的着色器阶段(Closest Hit Shader、Miss Shader 等)中调用 同一个回调函数
    • 当然,Non-inline 模式通常还需要配置 Shader Table(着色器表)

切换的便捷性

切换类型实现方式
软件 ↔ 硬件光追C++ 端仅需更改一个 枚举值(Enum)
Inline ↔ Non-inline差异主要在于 Shader Table 的设置 ,代码改动极小
CPU 光追部分平台甚至支持以相同接口进行 CPU 光线追踪

实际价值

  • 在 Inline 和 Non-inline 之间自由切换,有助于:
    • 验证假设(Validating Assumptions)
    • 测试新功能(Testing New Functionalities)
    • 找到最适合游戏的方案

混合光线追踪 GI(Hybrid Ray Traced GI)

两步骤架构

步骤技术说明
步骤 1逐像素光线追踪(Per-pixel Ray Tracing)结合 屏幕空间光线(Screen Space Rays)世界空间光线(World Space Rays)
步骤 2DDGI 风格的探针级联(DDGI-like Probe Cascade)5 个级联,共约 10,000 个探针 ;每帧更新约 1,000 个探针

光追命中数据存储

  • 光线追踪命中点的信息被存储为 一组 PBR 属性 ,写入一个 光追 GBuffer(Ray Tracing G-Buffer)
  • 这意味着命中点不是直接计算最终颜色,而是记录表面属性,后续再进行延迟光照——类似于延迟渲染的思路

要点总结

维度关键信息
反射层级SSR → GBuffer 立方体贴图 → 动态立方体贴图(三级回退)
立方体贴图阴影8 bit 存 8 个时间关键帧,运行时选最近两帧混合
季节变体每张立方体贴图最多 3 个变体,全游戏共 16,000 张
光追抽象Fusion 层统一了平台/硬件软件/Inline Non-inline 三个维度
混合 GI逐像素光追 + DDGI 探针级联(5 级 10,000 探针,每帧更新 ~1,000)
光追 GBuffer命中点存储 PBR 属性,延迟计算光照

光线追踪管线、加速结构与 Uber Shader


混合光线追踪管线流程

完整管线架构

屏幕空间追踪 → 世界空间追踪(硬件光线) → 命中缓冲区 → 去滤波/着色 → 降噪 → 最终合成

详细流程:

阶段操作说明
1. 屏幕空间追踪首先在屏幕空间中追踪光线作为 加速手段 ——硬件光线非常昂贵,先尝试在屏幕空间中找到命中
2a. 命中将命中结果存入 命中缓冲区(Hit Buffer)无需发射硬件光线
2b. 未命中保留当前 T 值,回退到世界空间追踪从屏幕空间光线的终点 继续步进 ,使用硬件光线遍历 BVH
3. 命中着色(Hit Deferred Shading)在延迟着色 Pass 中对命中缓冲区中的所有命中点进行 统一着色类似延迟渲染的思路
4. 未命中处理若某像素最终无命中 → 触发 Miss 事件 → 采样 探针缓存(Probe Cache)兜底方案
5. 第二次及后续弹射采样 DDGI 级联(DDGI Cascades) 获取间接光照的后续弹射仅第一次弹射使用光追,后续弹射用探针近似
6. 降噪对结果进行 降噪(Denoise)
7. 合成叠加可选的 RT-AO 项 + 镜面反射(如可用) → 最终图像

为何额外叠加 RT-AO

看似矛盾的做法

AO 理论上应该 已经包含在光照积分中 ,为何还要在最终阶段额外叠加一个 RT-AO 项?

三个实际原因

原因详细说明
频率混合问题系统混合了两种不同频率的信号——精确的光追结果与低频的辐照探针;探针会 衰减高频细节 ,尤其是 AO
四分之一分辨率追踪大多数平台上光线在 1/4 屏幕分辨率 下追踪,丢失高频细节
光栅世界与光追世界的差异某些几何体(如 草地 )出于性能原因 不存在于光追世界中 ,导致遮蔽信息缺失

补偿策略

补偿手段作用范围效果
RT-AO(艺术驱动)大型物体(房屋、树木等)帮助大物体 融入画面(Ground to the frame) ,效果显著
微妙的 SSAO 项厘米级细节(树冠、叶片等)弥补 1/4 分辨率追踪丢失的 近距离精细遮蔽

加速结构(Acceleration Structure / BVH)

灵活的配置选项

配置维度选项
纹理模式无绑定纹理(Bindless Textures)平均颜色替代(用于金属纹理等,面向低端平台)
剔除依据尺寸(Size)类型(Type) 过滤进入 BVH 的物体
LOD 选择使用 全局 LOD 偏移 决定放入 BVH 的 LOD 级别
微多边形管线基于 LOD 误差度量(LOD Error Metric) 选择近似几何——与 NVIDIA 推荐的方法一致
覆盖机制一切都可以 逐资产(Per Asset)逐材质(Per Material) 覆盖

关键说明

  • 加速结构的 GPU 开销很小 ——因为 GPU 驱动管线中所需的数据 已经存在
  • 在没有 Mega Geometry 等技术的情况下,LOD 误差度量是 当前最佳实践

Alpha Test 植被的光追难题与解决方案

问题描述

游戏中有 大量茂密森林 ,Alpha Test 植被在光追中带来两难困境:

方案问题
精确 Any Hit 着色器大量重叠叶片导致 Any Hit 调用极其昂贵 ,性能不可接受
限制命中次数遮蔽过度(过多阴影/黑暗区域
仅在植被上补偿效果不佳,更像是 hack

最终方案:按不透明度缩放三角形

团队尝试了一个 起初不被看好 的方案——结果效果出奇好:

  • 方法: 根据纹理的 平均不透明度(Average Opacity) 缩放三角形面积
    • 不透明度越低 → 三角形缩得越小 → 等效于部分透明
  • 本质: 将 Alpha Test 问题转化为 纯几何问题 ——用缩小的不透明三角形 近似 半透明效果

效果与优势

方面表现
性能比 Any Hit 方案 快 30%
漫反射 GI 质量与参考图像 非常接近
屏幕空间精度最近命中(Closest Hit)在 屏幕空间中解算 ,结果 像素级精确
遮蔽一致性所有层级的遮蔽关系保持一致
镜面反射作为额外收益,对 镜面光追 也是很好的近似——即使叶片三角形变成了不连续的集合

核心洞察: 两全其美——屏幕空间提供像素精确的最近命中,缩放三角形提供合理的全局遮蔽。


Uber Shader 方案

为何需要 Uber Shader

  • 因为使用 Inline 光线追踪 ,无法使用传统的 Hit Group Shader 分发
  • 需要一个 统一的 Uber Shader 来处理所有材质的光追着色

育碧的优势:严格的着色器管理

对比说明
Capcom 方案(参考)需要用 JSON 文件重新映射材质着色器——非常复杂
育碧 Anvil 方案由于 GPU 驱动管线的需求 ,引擎对 着色器种类有严格限制 ——Master Shader 数量受控
  • 这种严格管理使得编写 One-Fits-All Uber Shader 相对容易
  • 当然仍然存在一些 极端案例(Epic Fails) ,但可以通过 覆盖机制 轻松解决:
    • 可覆盖 BVH 中的内容
    • 可覆盖 LOD 设置
    • 可覆盖材质
    • 可覆盖着色器
    • 一切都可以覆盖

要点总结

维度关键信息
管线设计屏幕空间优先 → 硬件光线兜底 → 延迟命中着色 → DDGI 提供后续弹射
AO 补偿RT-AO + SSAO 弥补低分辨率追踪和光栅/光追世界差异
Alpha Test 植被按平均不透明度 缩放三角形 ——比 Any Hit 快 30%,质量接近参考
Uber Shader得益于严格的着色器管理,One-Fits-All 方案可行,极端情况靠覆盖解决
加速结构GPU 驱动管线数据复用 + LOD 误差度量 + 全面可覆盖

统一材质、软件光追、光探针与降噪管线


统一材质表示与季节处理

材质表(Material Table)

  • 使用前文描述的 GPU Database 材质表 存储统一材质表示
  • 光追命中时,通过 命中几何体 ID(Hit Geometry ID) 索引材质表
  • 季节变化通过 材质版本(Material Version) 处理:
    • 落叶季节:调整叶片材质以 减少过度遮蔽
    • 叶片颜色:使用 查找表(LUT) 驱动不同季节的颜色变化

天气与积雪

特性镜面反射光追漫反射光追
延迟天气(Deferred Weather)完整评估不评估(多次评估成本过高)
静态积雪烘焙在 地形远景(Terrain Vista) 中,仍可被漫反射访问
  • 漫反射中不评估天气是 已知的妥协 ,未来计划解决

加速结构(BVH)规模数据

典型城市场景(Xbox Series X)

指标数值
BLAS 数量~2,000
实例数量~30,000
BVH 总数据量320 MB
  • PC 端数据更大——因为更多物体参与光追(LOD 配置更激进)
  • 展示了 同一场景四个季节 的加速结构差异(植被变化导致 BVH 显著不同)

软件光线追踪(Software Ray Tracing)

定位与设计

方面说明
目标平台低端 PC(如 GTX 1070 等),未在主机上发布
技术来源Snowdrop 引擎 的软件光追栈非常相似,属于 Fusion 底层抽象层 的一部分
BVH 结构三级 BVH(Three-level BVH) ,在底层 API 中实现
更新策略依赖 空间分区(Space Partition) ,仅在 单元格加载或物体移动 时执行 局部更新(Partial Updates)

室内体积与探针系统

室内体积(Indoor Volumes)

  • 用于解决室内/室外 GI 漏光(Light Leaking) 问题
  • 平面列表(List of Planes) 定义
  • 同一份数据 被多个系统复用:
    • 烘焙 GI
    • 延迟天气(Deferred Weather)
    • 音频系统(Sound)
  • 用途:对探针进行分类(Classify Probes)

探针采样流程

采样位置 → 找到 8 个周围探针 → 按相同分类加权采样
  • 确保室内位置只采样室内探针,室外位置只采样室外探针

光探针的两级缓存

缓存级别类型说明
近辐射度缓存(Near-Radiance Cache)类似 DDGI(McGuire)精确但可能不稳定
辐射度缓存(Radiance Cache)兜底方案顶层稳定(Top-level Stable)

信号稳定化策略

  • 追踪更短的光线 ,减少噪声
  • 远距离 回退到辐射度缓存 ——牺牲精度换取稳定性
  • 演讲者展示的对比视频:一个具有 大量间接光照和狭窄开口 的挑战场景,稳定化前后差异显著
  • 明确的取舍: 精度略有下降,但稳定性大幅提升

半透明处理(Translucency)

半透明表面的光追策略

情况处理方式
直接命中半透明表面随机全面评估(Stochastically Fully Evaluate) 半透明表面
阴影光线命中半透明表面(如障子——日本纸门)在表面 两侧分别采样探针 ,使用 半透明因子(Translucent Factor) 混合

全方向聚簇光照结构(Omnidirectional Clustered Lighting)

与传统聚簇光照的区别

传统方案本作方案
视锥体对齐的聚簇体积(Frustum Cells)均匀网格(Uniform Grid) 围绕相机映射
单级结构两级层级 :I-Clusters → Clusters

结构细节

层级说明
I-Cluster包含 16×16×16 个 Cluster
Cluster 总数~260,000
剔除流程先执行 粗粒度 I-Cluster 剔除 → 再执行 细粒度 Cluster 级别光源剔除
  • 使用全方向(Omnidirectional)结构而非视锥体对齐的好处:光追光线可以 向任意方向发射 ,不受视锥体限制

光追镜面反射(Ray-Traced Specular)

开发背景

  • 项目末期紧急添加 ——在游戏延期后才有时间实现
  • 演讲者坦言 "能发布简直是奇迹"

技术特性

方面说明
目标平台高端平台 ——PS5 Pro 和 PC
设计基础复用 漫反射光追 GI 的大部分工作
开发难度相对容易——但暴露了 BVH 质量问题 ,这些问题在低频漫反射 GI 中不明显
降噪挑战镜面反射信号更高频,降噪难度更大

降噪管线(Denoising)

引擎中的三套降噪器

降噪器类型说明
自研降噪器(True Denoiser)SVGF 家族 算法内部开发
NRD(NVIDIA Real-time Denoisers)NVIDIA 提供的 ReBLUR
MSD(Snowdrop Denoiser)Snowdrop 引擎提供最终发布使用的方案

MSD 降噪器特性

  • 基于 时空滤波器(Spatio-temporal Filter) ,采用 递归模糊(Recurrent Blur) 方法——类似 A-BLUR
  • 额外支持:
    • 材质遮罩(Material Masking) ——为角色、植被、动态物体使用 特定启发式 处理 去遮挡(Disocclusion) 等挑战
    • 球谐降噪(Spherical Harmonics Denoising) ——信号以 YCoCg 格式存储,其中 Y 通道为 球谐函数

降噪效果展示(逐层对比)

原始光追输出(Raw RT Output)
    ↓ 标准降噪
降噪后结果
    ↓ 球谐降噪
球谐降噪后结果(更平滑的方向性光照)
    ↓ 最终光照合成
最终光照(Final Lighting)
    ↓ 后处理
最终图像(Final Image)
  • 纯烘焙 GI 的对比:演讲者表示纯烘焙 GI 的结果 "也还不错(Not too bad)" ——这正是可扩展管线的价值所在

小结:GI 管线的光谱

本作实现了从 全烘焙全光追 的完整 GI 光谱:

纯烘焙 GI ←→ 烘焙 + 探针缓存 ←→ 软件光追 ←→ 硬件光追漫反射 ←→ 硬件光追漫反射+镜面反射
(低端 PC)                                                              (PS5 Pro / 高端 PC)

光追性能、天气与季节系统


光追镜面反射效果与性能

视觉效果对比

  • 光追漫反射(RT Diffuse) 单独效果已经不错
  • 叠加 光追镜面反射(RT Specular) 后,即使场景反射性不强,仍能显著 增强画面扎实感(Grounding)
  • 关键优势:屏幕外物体(如商店外部)仍能 被正确反射

性能数据

组件Xbox Series X / PS5PS5 Pro
光追探针(RT Probes)~1 ms更低(硬件更强)
逐像素光追(Per-pixel RT)~4–5 ms更低
漫反射总计5–6 ms显著更低
镜面反射较昂贵可在目标分辨率下运行
  • 漫反射开销 分布在图形队列(Graphics Queue)和异步计算队列(ACQ) 之间

镜面反射的分辨率策略

  • 发布时使用 半分辨率:宽度 ÷ 2,高度保持不变
  • 选择半分辨率而非四分之一分辨率的原因:视觉效果显著更好,且预算允许
  • PS5 Pro 上:
    • 一切都更便宜
    • 漫反射光追成本 大幅降低
    • 最终 维持了目标渲染分辨率

天气与季节:系统化方法

整体架构

Atmos(大气模拟) ──┐
                    ├──→ Ambiance Graph(氛围图)──→ 驱动所有天气/季节逻辑
引擎输入 ──────────┘
系统职责
Atmos大气因子模拟与传播(流体模拟)
Ambiance Graph基于节点图的数据驱动天气逻辑控制
Multi-state Entities实体级别的季节/状态切换

Atmos 大气模拟系统

  • 独立可做一整场演讲 的复杂系统
  • 在玩家周围使用 低分辨率体素数据 进行运行时模拟
  • 模拟并传播的大气因子:
因子说明
蒸汽(Vapor)
温度(Temperature)
湿度(Humidity)
风(Wind)使用体素碰撞
  • 模拟结果输出到下游系统:
    • 体积云(Volumetric Clouds) ——驱动云的 形成与消散
    • 风和降雨 效果
  • 右侧展示了 随海拔变化 的各物理量分布

Ambiance 系统演进

系统特性
旧版 Ambiance Manager曲线驱动,逻辑有限,控制昼夜光照、后处理等
新版 Ambiance Graph基于 节点图系统(Another Graph System) ,完全数据驱动
  • Ambiance Graph 的工作方式:
    • 消费输入 :来自引擎和 Atmos 的数据
    • 驱动输出 :整个天气和季节技术逻辑
    • 完全由技术美术(Tech Art)控制 ——TA 可以决定一切行为

延迟雨渲染(Deferred Rain)

技术基础

  • 基于 Sébastien LagardeWet Block Post 系列博文(业界知名方案)

材质修改逻辑

步骤操作
湿度(Wetness)根据湿度等级 压暗反照率(Darken Albedo) + 降低粗糙度(Decrease Roughness)
水坑(Puddles)在湿度之上叠加水坑效果

数据存储

  • 湿度遮罩存储在 GBuffer 中,仅占 单个 float
  • 角色不参与 统一湿度系统——角色使用独立的 动态角色层系统(Dynamic Character Layer System)

效果序列

干燥场景 → 湿润场景(反照率压暗 + 粗糙度降低)→ 叠加水坑

积雪系统(Snow System)

三层积雪架构

层级名称说明
1深雪(Deep Snow)数据驱动的印章系统(Stamper),可捕获纹理并 变形地形或任意高度图
2延迟积雪(Deferred Snow)类似延迟雨的动态积累系统
3冷/暖区域由技术美术通过 静态/动态积雪遮罩(Snow Mask) 绘制

延迟积雪的材质修改流程

原始材质
  ├─ 1. 反照率(Albedo)→ 向雪白色插值(根据当前积雪等级)
  ├─ 2. 粗糙度(Roughness)→ 同样向雪的粗糙度插值
  ├─ 3. 半透明度(Translucency)→ 降低(主要影响植被,积雪越多越不透明)
  ├─ 4. 微可见性(Micro Visibility)→ 遮罩排除
  └─ 5. 法线朝向阈值 → 垂直表面不积雪(模拟真实物理行为)

完整天气循环

暴风雪 → 积雪逐渐累积 → 暴风雪消散 → 积雪缓慢衰减 → 转变为湿润+水坑 → 最终融化干燥
  • 整个循环逻辑 完全由 Ambiance Graph 驱动

室内排除与粒子遮挡

室内天气排除

系统方法
延迟雨/雪复用 室内体积(Indoor Volumes) ——与烘焙 GI、光追 GI 等使用 同一份数据
遮挡判定将室内体积光栅化为 室内深度图(Indoor Depth Map) ,用于确定天气遮挡因子
性能非常廉价——室内体积本质上 只是平面(Planes)

雨粒子遮挡

步骤说明
渲染遮挡深度图雨方向为朝向 渲染周围环境的深度图
遮挡粒子用此深度图遮挡雨粒子和涟漪
窗户穿透雨粒子 可以穿过窗户进入室内 ——增加真实感

系统复用总结

一个值得注意的架构模式是 室内体积数据的极高复用率

室内体积(平面列表)
  ├── 烘焙 GI 探针分类
  ├── 光追 GI 探针分类
  ├── 延迟雨排除
  ├── 延迟雪排除
  ├── 延迟天气系统
  └── 音频系统

这种 一份数据服务多个系统 的设计,体现了成熟引擎架构中数据驱动与系统解耦的理念。

可扩展性、性能管理、总结与 Q&A


平台管理器(Platform Manager)

设计背景

  • 由于性能模式和画质模式使用 不同的 GI 系统(烘焙 GI vs 光追 GI),帧结构 差异很大
  • 需要一套系统化的方案来管理所有配置

核心概念

概念说明
数据驱动性能设置平台上下文 实现,不仅用于引擎和图形系统
UI 自动生成所有设置 自动生成编辑界面 ,且支持 实时编辑
Profile(配置文件)性能模式、画质模式等——修改后需要 重新加载世界
Profile Boot Settings需要 重新启动可执行文件 的设置

三种运行时调整机制

机制触发方式用途示例
Air Context游戏逻辑触发(进入菜单、照片模式、返回游戏世界)照片模式下提升毛发渲染质量
Modifiers数据触发——可通过绘制或 3D 体积触发洞穴中禁用某些室外系统,解决局部性能问题
Profiles玩家选择性能模式 vs 画质模式

平台管理器的定位

Platform Manager 是 Anvil 引擎中的一等公民(First-class Citizen)

  • 极大便利了 性能分析(Profiling) 工作
  • 可以 模拟主机设置(在编辑器中,虽有限制)
  • 与硬件厂商协作时非常有用——可以按厂商反馈快速调整配置

资源与性能追踪工具

内存追踪

工具级别功能
高层级视图追踪 资源生命周期 ,定位帧内 内存峰值
低层级工具检查 内存分配器 ,调试 内存浪费不期望的内存别名模式(Memory Aliasing Patterns)

性能遥测(Telemetry)

  • 游戏内置 大量遥测计数器 ,存储在数据库中
  • 追踪示例:
    • 动态分辨率因子 ——世界中每个位置的数据
    • GPU 性能回归 ——跨构建版本在 PS5 上对比
    • 其他各类性能指标

总结与未来展望

项目成就

里程碑说明
首款 Monorepo + 共享引擎游戏AC Shadows 是首款以 Monorepo 和共享引擎模式发布的游戏
最大的 AC 游戏有史以来规模最大的刺客信条
最可扩展的 Anvil 版本迄今为止 Anvil 引擎最具可扩展性的版本

未来改进方向

方向详情
微多边形(Micro Polygon)希望在 更多管线中支持 ,进一步提升几何细节——此次因需提前确定多边形预算而偏保守
光追 GI 更普及烘焙 GI + 光追 GI 并存 对开发者非常困难 ;希望让光追更为主流以 简化管线 ;但认为给玩家选择始终是好事
QA 复杂性昼夜 × 四季 × 天气 组合使 QA 极其困难 ;升频器(Upscaler)的碎片化更加剧了问题;呼吁行业层面 重新思考 如何应对这种复杂性
基于图的天气/季节原型迭代非常方便,但 QA 和问题复现困难;需要 更多迭代和成熟度
帧图模块化与定制化希望在 Monorepo + 共享引擎的背景下进一步推进 帧图的数据驱动调度

Q&A 精选

Q1:macOS / iOS 移植的挑战?

问题: 最近也在 macOS 和 iOS 上发布了,与 PC/主机相比有何不同?

回答:

  • 平台跨度很大(M1 到 M4),低端平台是挑战
  • 通过 合理妥协(不影响游戏体验的功能降级)成功运行
  • 主要挑战是开发环境 ——在 Mac 环境下使用 Xcode 工作,团队不太习惯
  • 低端 Mac 上可能使用了 软件光追(Software Ray Tracing)
  • 演讲者坦言:由于 Platform Manager 的配置 极其动态 ,有时自己都不确定某个平台具体用了哪些特性

Q2:微多边形管线是否支持植被(Alpha Test)?

问题: 类似 Nanite 中植被压缩的挑战,微多边形管线是否优化了植被?

回答:

  • 目前不支持 Alpha Test
  • 原因:现有 GPU 驱动管线 处理 Alpha Test 已经 非常高效 ——能渲染数百万三角形的森林,无性能问题
  • 策略:先把不透明几何体做对 ,之后再攻克 Alpha Test
  • 承认这是一个挑战,希望 花时间做对

Q3:多帧率目标(33ms vs 16ms)下的帧时间预算?

问题: 支持 30fps 和 60fps 多个目标,帧时间预算如何规划?

回答:

  • 最大问题 是有/无 RTGI 的帧结构差异巨大——性能模式和画质模式是 两种完全不同的帧
  • 尽量让 GPU 调度 尽可能接近 ,以避免各模式特有的 Bug
  • 承认这是 一个头痛的问题 ,未来可能需要 按模式定制调度
  • Monorepo 环境下同一代码库服务多个游戏,进一步增加复杂性
  • 已开始探索 数据驱动的帧图调度 ,但此次项目中不敢激进推进

整场演讲核心要点回顾

                        AC Shadows 渲染技术栈
                              │
        ┌─────────────────────┼─────────────────────┐
        │                     │                     │
   共享引擎架构           渲染管线              系统化天气/季节
   ├─ Monorepo           ├─ GPU-Driven        ├─ Atmos 大气模拟
   ├─ Anvil 引擎          │  Pipeline          ├─ Ambiance Graph
   ├─ Platform Manager   ├─ 微多边形           ├─ 延迟雨/雪
   └─ Fusion 抽象层       ├─ 混合 GI            ├─ Multi-state Entities
                         │  (烘焙+光追)        └─ 密度图 + 季节变体
                         ├─ 光追抽象层
                         │  (HW/SW, Inline/Non-inline)
                         ├─ 统一材质表
                         └─ 降噪 + 合成

核心理念: 在开放世界规模下,通过 数据驱动、分层抽象、可扩展架构 ,实现从低端 PC(GTX 1070)到 PS5 Pro 的全平台覆盖,同时支持昼夜、四季、天气的完整动态变化。