The Technical Art of The Last of Us Part II

The Technical Art of The Last of Us Part II by Waylon Brinck and Steven Tang || SIGGRAPH 2020 - YouTube


项目背景与技术挑战

团队角色定位

  • Naughty Dog 的 技术美术(Technical Artist) 定位为 "半程序员、半艺术家" ——既有计算机科学学位,也掌握构图、色彩理论等美术知识,并熟悉实际资产制作的工具与工作流。
  • 本次演讲涵盖两方面:具体 渲染技术 与技术美术团队在生产过程中的 成长与升级 。

从《神秘海域4》到《最后生还者 Part II》的跨越

  • 《神秘海域4》 的渲染已达到里程碑级水准(详见 SIGGRAPH 2016 演讲)。
  • 《最后生还者 Part II》 面临全新且更困难的渲染挑战:
    • 大量场景依赖 环境光照(Ambient Lighting) ——这是极难做好的视觉风格,缺乏强烈直射光来"掩盖"材质缺陷。
    • 大量 玻璃、雨水 及其他复杂表面。
    • 环境种类远超以往任何项目。
    • 细节关注度极高 ,早期角色渲染测试暴露出巨大差距。
  • 结论:不仅要升级 技术本身 ,还要升级 技术美术团队的工作方式 。

Naughty Dog Uber Shader 系统

总体概况

  • Uber Shader 驱动游戏中 几乎所有表面 ,仅有天空、水体和粒子例外。
  • 代码量约 48,000 行 (不含生成代码)。
  • 这是项目 最先着手 的工作:清理旧有混乱接口、重构代码,为后续功能打下坚实基础。

核心架构:分层材质系统(Layer-Based Material System)

基本概念

  • 材质由 多个层(Layer)逐层叠加 构建,概念类似 Photoshop 图层 。
  • 示例:一个地面材质 = 混凝土底层 + 油毡层 + 湿润层 + 污渍层。
  • 每个层可以是独立的 单层材质 ,在关卡其他地方单独使用,美术通过 合成(Composite) 将它们组合成一个多层材质。

界面设计

面板功能
Layers Panel(图层面板)显示图层堆栈,蓝色边框标识 继承自其他材质(Inherited) 的层
Features Panel(功能面板)控制该层启用哪些功能(基础 / 高级)
多标签页(Tabs)每个标签页控制该层行为的不同方面(BRDF、混合、UV 等)

BRDF 参数体系

主要参数

  • 包含业界常见参数,同时有 Naughty Dog 独有参数 :
    • Height Map(高度图) ——用于层间混合与视差效果
    • Fuzz(绒毛/模糊) ——非标准参数,用于布料等特殊表面
  • 还包含写入 G-Buffer 的其他数据:光照数据、 运动向量(Motion Vectors) 等。
  • 针对 皮肤(Skin) 和 头发(Hair) 等有专门的特殊参数(详见 Ramy 在 SIGGRAPH 2016 的演讲)。

G-Buffer 设计

  • 整体概念延续了 G-Buffer 打包(Packing) 与 延迟排列(Deferred Permutations) 的方案。
  • 相比《神秘海域4》,G-Buffer 通道做了 大幅调整 。

参数交互设计原则

  • 每个参数的界面 尽可能简洁 ,内建少量最常用的操作与调整。
  • 特殊参数(如 Wetness / 湿润度 )独立于图层堆栈进行 累积(Accumulate) ,最终统一修改 BRDF 输出值后写入 G-Buffer。
  • 高级参数放在 子菜单中隐藏 ,既方便新手 发现功能 ,又让资深美术拥有 更强能力 。

Shader Package(着色器包)

  • Shader Package 并非特殊机制,而是一组 预打包的控件集合 ,用于更复杂的功能设定。
  • 通常影响 多个 BRDF 参数 ,或由 Gameplay 事件驱动 。
  • 典型示例—— 角色脏污包(Character Dirt Package) :
    • 同时影响 颜色(Color) 、 法线(Normal) 和 粗糙度(Roughness) 。
    • 内置与 Gameplay 事件动态联动的全部代码。

层间混合系统(Layer Blending)

基础混合模式

  • 示例:红色实色层叠加在 50% 灰色层之上。
  • 美术开启 基于顶点色(Vertex Color) 的混合模式即可简单混合。

丰富的混合方式

混合类型说明
纹理混合(Texture Blend)基于贴图进行混合
斜面混合(Slope Blend)基于世界空间中的 顶点法线 进行混合
各类调整对最终混合结果或中间步骤结果调节 对比度、柔和度 等

元功能(Meta Features)

Blend Mode Previous(前层混合模式)

  • 取 上一层的最终混合结果 ,应用到当前层进行 调制(Modulate) 。
  • 非常适合 继承(Inheritance) 场景:美术想让某层受限于前一层的混合结果,但不想重复创建复杂的混合设定。

累积高度图(Accumulated Height Map)

  • 可以使用 当前层以下所有层的累积高度图 进行混合判断(后续会详细讨论)。

UV 流系统(UV Streams)

基础功能

  • 支持 选择 UV 集(UV Set) 和标准变换。
  • UV 流 不与层绑定 ——美术可为每层选择不同 UV 流,或所有层复用同一流。

高级功能

功能说明
视差遮蔽映射(Parallax Occlusion Mapping / POM)基于高度图的深度视差
UV 扭曲(Distortion)UV 变形效果
UV 动画(Animation)各类 UV 滚动/动画效果

Flow 技术(重点)

  • 由程序员 Carlos 开发的 Flow 技术 :
    • UV 持续滚动,但在 两个相位偏移的纹理采样之间交叉淡入淡出(Crossfade between two phase-shifted texture samples) 。
    • 这防止了 UV 值不断增大时纹理被 拉伸到无穷 的问题。
  • 该技术被 完全集成 到整个 Uber Shader 架构中:
    • 每个纹理采样器、每个标签页 都能以这种 多采样相位偏移模式 运行。
    • 美术无需特殊设置;技术美术添加新采样器时也自动兼容。
  • 附带优化细节(对美术不可见):
    • 任何 UV 动画控件会 自动写入正确的运动向量(Motion Vectors) ,确保时间抗锯齿(TAA)等后处理正常工作。

排列组合爆炸与优化策略(Permutation Management)

问题

  • 每当美术开启新功能,就会生成一个 新的 Shader 二进制(Shader Binary) 。
  • 美术需要承担相应的 CPU 开销和关卡内存成本 。
  • G-Buffer Pass 基本上 每个材质对应一个唯一 Shader Binary 。

优化手段

  • 编程团队进行了 去重优化(Deduplication) :针对 深度(Depth)和阴影(Shadow) 等 Pass 合并相同的 Shader Binary。
  • 尽管优化需要投入大量时间,团队认为这种 材质多样性对最终画面效果至关重要 。

特殊功能示例

Border Blend(边界混合)

  • 位于 BRDF 标签页的特殊功能,简化常见操作。
  • 典型用例:当一个材质继承叠加到另一个材质之上时,过渡区域 几乎总需要特殊处理。
    • 例如:涂漆石膏(Painted Plaster)在过渡区域呈现 更暴露、更脏湿 的外观。
  • Border Blend 封装了美术所需的全部过渡功能。
  • 该功能最初设计简单,但因使用频率极高,最终接口变得更复杂——美术乐于接受,因为它极大简化了材质创建:
    • 可以在两层 过渡区域中采样一张完全不同的纹理 ,这对最终效果至关重要。

智能贴花系统(Smart Decals)

  • G-Buffer 被 解包为一个虚拟层(Virtual Layer) ,位于贴花图层堆栈的最底部。
  • 美术可以使用 任何混合操作 来对下方表面的 G-Buffer 通道进行混合。
  • 优势:
    • 贴花在 多种不同表面上高度复用 。
    • 贴花能 响应其覆盖表面的属性 。
    • 可使用下方表面的 高度图(Height Map) 实现更丰富的混合效果。

阶段总结与设计哲学

  • 虽然 Uber Shader 架构在《神秘海域4》中已建立,但团队抓住机会进行了 全面改进与标准化 。
  • 核心设计哲学:
    • 聚焦于 小型、可复用的模块(Small, Reusable Modules) 。
    • 代码库保持 整洁 → 材质 优化良好且易于扩展 。
    • 界面设计兼顾 新手友好 与 高级能力 。
  • 最终成果:一个对美术 易用 、功能 极其丰富 的着色器系统,为后续所有渲染特性的开发奠定了坚实基础。

团队协作模式的反思与重建


问题的暴露

  • 技术美术团队在项目推进过程中,逐渐形成了 不健康的工作习惯 :
    • 技术美术变成了程序团队与美术团队之间的 一堵墙(Wall) ,而非桥梁。
    • 程序员感觉自己成了 服务部门(Service Department) ,而非美术的 合作伙伴(Partners) 。
    • 程序员 失去了创造性协作的参与感 ,觉得自己与游戏脱节,工作 得不到认可 。

改进计划

  • 经过深思熟虑,团队制定了 回归正轨的方案 ,核心方向有三点:
目标具体含义
从墙变为桥梁技术美术应当 促进 程序与美术的直接沟通,而非 阻隔
健康的协作机制在复杂系统开发上建立 合理的分工与协作流程
提升代码标准技术美术的代码质量虽不必完全达到程序员水平,但需达到 让程序员信任 的程度
  • 这既是为了 项目质量 ,也是为了修复 团队关系 。

高度图(Height Map)深度集成

这项技术既是重要的渲染升级,也是团队 实践新协作标准 的试金石。


高度图的历史与新定位

  • Naughty Dog 从 《神秘海域1》 起就使用高度图作为 混合遮罩(Blend Mask) 。
  • 在《最后生还者 Part II》中,团队看到了高度图在 整个管线中更广泛应用 的潜力,决定进行 深度集成 。

界面与参数设计

设计原则

  • 界面尽可能 简洁且规范 。
  • 所有缩放单位统一为 厘米(cm) ,最大范围 ±10 cm 。
  • 源纹理中灰度值 0.5 = 中性高度(Neutral Height) ,美术对此非常直观熟悉。

主要功能

  • 凸起效果(Raised) :让表面层向上突出,如砖墙上的灰泥层。
  • 凹陷效果(Inset) :让表面向下切入,如沥青上的裂缝。
  • 层偏移(Offset) :上下偏移图层位置,在处理 材质继承(Inheritance) 时非常关键,极大增加了材质的 通用性与灵活性 。

迭代过程

  • 经过与美术的 大量迭代与测试 ,初始设计 在整个项目期间未做改动 。
  • 教训:"迭代本身不是坏事,但 前期投入足够的设计时间 是值得的。"

高度图的具体应用

屏幕空间环境光遮蔽(Screen Space Ambient Occlusion)

  • 传统 SSAO 仅使用 深度缓冲 + 法线 。
  • 集成高度图后,即使是 平面几何体 ,也能生成更丰富的 AO 细节。
  • 优势 :
    • 响应 图层混合(Layer Blends) 的变化。
    • 与其他几何体 相交时能正确交互 。
    • 无需将 AO 烘焙到纹理中。

屏幕空间阴影(Screen Space Shadows)

  • 砖块、窗户玻璃等都能投射出微小的 接触阴影(Contact Shadow) ,增加了 深度感与可信度 。

效果评估

  • 坦诚地说,这两个效果在游戏实际运行中 大多数时候非常微妙 ,视觉上不太显眼。
  • 但由于高度图已 深度集成在管线中 ,这些效果几乎是 "免费的" 。
  • 团队期望在 下一代硬件 上,能负担更多采样次数,使效果更加明显。

贴花系统(Decals)—— 最成功的应用

  • Gameplay 驱动的贴花 (如 血液贴花 )可以读取下方表面的高度图数据。
  • 效果极为出色:
    • 血池会 自然嵌入地毯纹理 ,并 避开掉落的表面碎片 (如天花板石膏块)。
    • 同一套血液贴花在 地板、瓷砖、沥青、凸起瓷砖 等不同表面上都能 自适应整合 。
  • VFX 团队接入高度图缓冲区非常简单,能 轻松利用 这一功能。

实时法线生成(Real-Time Normal Generation from Height Map)

核心算法

  • 基本计算非常简单:

  • 使用 ddx / ddy 求导 + 叉积(Cross Product) 生成法线。

固有问题

  • 此方法天然存在 多边形面片化(Polygon Faceting) 和 像素化伪影(Pixel Artifacts) ,这是数学本质决定的,无法完全避免。

实际应用:图层混合边界

  • 唯一 无法预烘焙法线 的地方 = 图层之间动态生成的混合区域 。
  • 通过 Border Blend(边界混合) 功能控制该区域。
  • 混合区域的 高频噪声 天然地 遮盖了像素化伪影 ,因此效果非常好。
  • 代码中通过 blend mask 参数限定只在 图层交界区域 生成法线,精确控制生效范围。

协作反思:成功与教训

成功之处

方面评价
美术界面设计巨大成功,前期设计充分,整个项目未做修改
系统整体设计高度图深度集成管线的架构非常合理
贴花等特定用例效果远超预期

失败与反思

  • 屏幕空间阴影的原型开发 暴露了协作问题:
    • 演讲者做了大量 原型工作(Prototyping) ,获得了正确结果。
    • 但 高度优化的实现 涉及 极难的数学和编程 ,超出了技术美术的能力范围。
    • 关键错误 :没有在早期与程序员达成共识—— 这只是概念验证(Proof of Concept) 。
    • 如果一开始就明确定位,原型可以 做得更快 ,代码也可以 与主代码库隔离 。
    • 频繁地 逐行请教程序员 反而造成了摩擦——程序员认为技术美术要么应该 独立完成 ,要么应该 直接交接 。
    • 最终由程序员 Hawar 接手完成了 出色的最终实现 。

核心教训

技术美术做原型验证时,应明确边界:前期定位为"概念验证",隔离代码,减少对程序员日常工作的干扰;确认可行后及时交接给程序员做产品级实现。 结果可以一样好,但过程中的摩擦可以大幅减少。

湿润与雨水渲染系统


开发背景与团队状态

  • 此阶段技术美术团队仍处于 "证明自身价值" 的模式中。
  • 演讲者坦承:作为对高度图开发中过度依赖工程师的反弹,这次选择 几乎独立完成所有工作,不太寻求程序团队的输入 。
  • 事后反思:这种方式 长远来看并不健康 ,但属于团队成长过程中的阵痛。

湿润系统基础

继承自《神秘海域4》的核心机制

  • 核心思路:用 单一的湿润参数(Wetness Parameter) 驱动表面从干燥到积水的 完整渐变过程 :

  • 该参数会 同时影响所有 BRDF 参数 (颜色、粗糙度、反射率等)。

新挑战

  • 《最后生还者 Part II》包含 大量雨天场景 和湿润表面,初始技术推进始于 巴黎游戏展(Paris Game Show)预告片 的制作。

湿润遮罩与流水动画

简化美术工作流

  • 旧方式 :美术需要同时制作 高光遮罩(Specular Mask) 和 配套法线贴图(Normal Map) ,两者难以同步动画。
  • 新方式 :美术 只需制作一张湿润遮罩(Wetness Mask) ,系统自动从中 派生所有所需数据 。

流水动画技巧

  • 美术绘制一张 静态遮罩 ,标记水流路径(水纹/细流)。
  • 引擎叠加一张 滚动的云纹理(Scrolling Cloud Texture) ,利用之前描述的 Flow 技术 进行交叉淡入淡出。
  • 效果:水流在角色皮肤上 自然流淌并不断变化 。

高光法线系统(Specular Normal)

核心概念

  • 标准做法 :法线贴图同时影响漫反射和高光反射。
  • 新系统 :启用 Specular Normal 功能后,系统激活 不同的延迟渲染排列(Deferred Permutation) 和 不同的 G-Buffer 配置 ,将法线分为两套:
法线类型用途读取位置
漫反射法线(Diffuse Normal)控制漫反射光照、次表面散射等SSS Pass、最终延迟着色
高光法线(Specular Normal)控制高光反射IBL Pass、最终延迟着色

管线中的正确传递

  • 次表面散射通道(Subsurface Pass) :只读取 漫反射法线 。
  • IBL 通道(Image-Based Lighting Pass) :只读取 高光法线 。
  • 最终延迟着色器(Final Deferred Shaders) :同时读取 两种法线 。

应用于皮肤上的水滴

  1. 对湿润遮罩施加 阈值(Threshold) 处理。
  2. 将结果缩放到 真实世界 ±10 cm 的高度图范围。
  3. 利用之前介绍的 从高度图实时生成法线 的技术,生成高光法线。

为什么需要分离法线?

  • 如果高光和漫反射 共用同一法线 ,水滴在皮肤上看起来会像 血管/静脉(Veins) ,而非自然的 高光亮点 。
  • 分离后,水滴只在 高光通道 产生凹凸效果,漫反射保持皮肤原始法线,视觉上自然得多。

水滴焦散与阴影模拟(Caustic Refraction & Shadowing)

物理原理

  • 以 玻璃半球 为类比模型:
    • 光线穿过水滴时,在 高光点 处能量汇聚(焦散高亮)。
    • 在半球 对侧 形成投射阴影。

实现思路

  1. 已知当前像素的 渲染法线 和来自湿润遮罩的 高度值 。
  2. 利用这些信息 构建虚拟水滴的数学模型 。
  3. 由于 只能访问当前像素(无法读取相邻像素),需要进行 反向投影(Reverse Projection) ,推算最终的 折射光线方向 。
  4. 最终判定该像素应为 高亮区(Highlight) 还是 阴影区(Shadow) 。

代码质量评价

  • 演讲者坦率地称这段代码是 "一个巨大的 Hack" 。
  • 但强调这是一个 基于真实物理现象建模 的 Hack,尽可能忠实于实拍参考。

推广应用

  • 控件被 通用化 后,应用于游戏中几乎所有表面:
    • 地面、汽车、玻璃 等。
  • 积水(Puddles) 也得到升级:
    • 积水底面使用 漫反射法线 (表现水下地面纹理)。
    • 水面使用 高光法线 (表现平坦或波纹水面)。
    • 差异虽细微,但 可感知 。

开发质量自评

评估维度结果
代码质量除焦散部分外, 整体编写较为干净
技术复用高度图技术 得到高效复用
美术可用性功能设计以 美术易用性为优先
高光法线系统实现 高效 且 高度可扩展 ,积水即为扩展应用的典范

更多雨水和湿润相关技术可参见 Artem Kovalovs 在 SIGGRAPH 2020 的演讲 "GPU-Driven Effects of The Last of Us Part II" 。


渲染技术验证方法论


核心目标

  • 物理基础渲染(PBR) 的终极目标是 尽可能匹配现实 ,即使永远无法完全达到。

验证手段

地面真值模式(Ground Truth Mode)

  • 在渲染器中维护一个 昂贵但精确的参考渲染模式 ,用于对比检验实时渲染效果。

与现实对照

  • 利用游戏角色 直接来自真人扫描 的优势(如角色 Abby 与其真人模特)。
  • 在现实中精确搭建 匹配的摄影与灯光条件 :
    • 测量 相机距离、高度 。
    • 测量 光源强度、精确角度与高度 。
  • 将引擎渲染结果与真实照片进行 逐像素对比 。

能量差异评估

  • 评估正确性的方式:测量渲染结果与地面真值之间的 能量差异(正或负) 。
  • 差异会随以下因素变化:
    • 摄像机入射角
    • 光源角度
    • 局部几何形状
  • 实际操作中 并没有量化测量工具 ,而是通过 目视对比 与 持续讨论 来驱动优化方向。

关于瑕疵(Artifacts)的重要原则

不连续性问题(Discontinuities)

  • 需要特别警惕 空间上或时间上的不连续性 。
  • 经典案例: 屏幕空间反射(SSR) 本身相当精确,但当它 回退到 Cube Map 时,如果两者 不匹配 ,会产生 极其引人注目的硬边 。

"蚊子效应"

  • 硬边和局部高对比区域会创造大量 视觉焦点 ,像 耳边嗡嗡叫的蚊子 一样:
    • 抢夺玩家注意力 ,偏离场景真正的视觉重心。

核心取舍原则

即使意味着理想情况下渲染精度略有降低,也值得去消除各类视觉瑕疵。

  • 换言之: 感知上的正确性(Perceptual Correctness) 有时比 物理上的绝对正确性(Physical Correctness) 更重要。

眼睛着色器(Eye Shader)重制


渲染架构概述

眼睛的特殊渲染路径

  • 在 Naughty Dog 引擎中,眼睛采用 前向渲染(Forward Rendered) ,但仍然 写入 G-Buffer 。
  • 全屏通道(如 次表面散射、IBL、后处理 等)基于 G-Buffer 数据运作。
  • 最终由一个 前向通道 读取这些缓冲区并计算最终光照。
  • 该前向通道是 游戏中最昂贵的着色器 ,但由于眼睛在屏幕上 占比极小 ,实际帧率影响 微乎其微 (即使特写镜头也 低于 1 毫秒 )。

起点与问题

  • 初版(公布预告片中 Ellie 的眼睛)虽然经过精心制作,但看起来 有些卡通化(Cartoony) ,且只在 特定光照和摄像机角度 下效果好。
  • 目标:实现更加 动态、栩栩如生 的眼睛。

研究方法论

参考资料

  • Jorge Jimenez 的 "Next Generation Character Rendering" 论文是绝佳起点。
  • 团队还进行了 自己的摄影参考拍摄(Photo Shoot) 。

关键方法论建议

像科学家一样工作 :提出假设 → 设计实验 → 测量结果 → 发现意外的微妙差异。

  • 网上有大量眼睛参考图,但 自己拍摄参考 不可替代。
  • 对 任何物理现象 的分析都应遵循此流程:仔细测量和观察是理解效果的关键。
  • 意外的微妙发现 往往是推进技术的真正动力。

实现策略

  • 将眼睛着色分解为 所有微观特征(Micro Features) ,逐一实现并叠加。
  • 大部分功能直接参考 Jorge 论文实现,演讲仅聚焦于 与其不同或改进的部分 。

核心渲染特性

屏幕空间阴影——眼睑与睫毛投影

实现方式

  • 采用 暴力光线步进(Brute Force Ray March) 方法。
  • 硬编码步进距离 ,采样 不透明 + Alpha 深度缓冲区(Opaque + Alpha Depth Buffer) 。
  • 从该深度缓冲区中获取 睫毛的阴影信息 。

优势

  • 比业界常见方案(动画平面 或 查找纹理 / Lookup Texture )可靠得多 。
  • 能捕捉 眼睑形状 和 眉毛位置 的微妙差异(如 Joel 的特写镜头)。

扩展应用——IBL 遮蔽

用途方法
高光 IBL 遮蔽沿 摄像机反射向量(Camera Reflection Vector) 进行光线步进
漫反射遮蔽直接读取 现有的屏幕空间环境光遮蔽(SSAO)缓冲区

焦散光折射(Caustic Light Refraction)

实现思路

  • 本质上是一个 临时性函数(Ad Hoc Function) ,但经过精心调校以 尽可能匹配参考 。
  • 利用 双法线系统 :
法线类型作用对象
漫反射法线(Diffuse Normal)照亮 虹膜内表面 、驱动 次表面散射
高光法线(Specular Normal)用于 角膜外表面
  • 这样设计的好处:IBL 反射等系统 无需了解眼睛着色器的任何特殊知识 ,只需处理 G-Buffer 中的数据即可。

实现质量的坦诚评价

  • 焦散效果的代码 确实很 Hack 。
  • 但由于渲染被拆解为 极其细粒度的真实世界现象 ,即便是 Hack 也可以 独立测量正确性 并 独立调优 ,不影响其他元素。

角膜缘(Limbus)——虹膜周围的暗环

物理原理

  • 角膜缘 不是眼睛颜色的一部分 ——它是 角膜折射 将光线聚焦偏离边缘所产生的视觉效果。
  • 常见做法是直接 画进漫反射纹理 ,但这无法正确响应光照变化。

参考观察

  • 当光线 正面照射 时,角膜缘 几乎消失 。
  • 当光线以 掠射角(Glancing Angle) 照射时,角膜缘 非常明显 。

实现方式

  • 提供角色美术对 角膜缘强度(Limbus Intensity) 的控制(个体差异大)。
  • 对环境光照:在 半球上 8 个方向 暴力计算角膜缘强度,然后取平均值。
    • 实质上 模拟 8 个光源方向 的角膜缘效果。
  • 确保美术控制在 所有光照类型 下给出 一致的视觉结果 。
  • 曾考虑直接应用于 球谐函数(Spherical Harmonics)查找 ,但其带来的微妙提升 不值得额外开销 。

泪线(Tear Line)

问题性质

  • 与其说是模拟物理能量传输,不如说是 用实用方案解决实际问题 。

实现方式

  1. 使用 G-Buffer 贴花(G-Buffer Decal) :一块附着在眼睑上、随眼睑动画的几何体。
  2. 对 G-Buffer 进行 多采样模糊(Blurred Multi-Sample) 。
  3. 混入一个 凹凸不平的水面法线(Lumpy Water Normal) 。
  4. 将结果 写回 G-Buffer 。

影响通道

通道是否受影响
法线(Normal)✅ 主要效果来源
颜色(Color)✅
粗糙度(Roughness)✅
高光(Specular)✅

巩膜次表面散射修正(Sclera SSS Fix)

发现问题

  • 在 掠射角(Grazing Angle) 下,巩膜(眼白)的次表面散射能量 不足 ,表现为眼白边缘只有一圈微弱的光环。

解决方案

  • 问题并非代码错误,而是需要调整 次表面散射通道所使用的漫反射法线贴图 。
  • 原来设定为 凸面(Convex) ,实际应为 凹面(Concave) 。
  • 团队认为这是 物理上合理的解决方案,而非 Hack 。
  • 关键启示 :如果没有自己拍摄参考,这个问题 不会被注意到 。

牙齿着色器(Teeth Shader)

  • 将许多眼睛着色器的自定义技术 应用到牙齿上 ,牙齿同样采用 前向渲染 。
  • 灵感来自 London Studio 的 James Anser 。

关键技术点

技术说明
屏幕空间阴影与眼睛类似的实现
自定义次表面散射使用 更小的散射半径 ,并加入特殊处理防止 嘴唇光照溢出到牙齿上
微湿润法线(Micro Wetness Normal)源自 "Humanness" 论文中的技术

阶段性总结与团队变动

成果评估

  • 前期研究(先行技术 + 自拍参考)极具价值,提供了 清晰的逐特征实现路线图 。
  • 新眼睛着色器效果优秀,代码 健壮可靠 。

团队协作状态

  • 技术美术团队 巩固了技术基础 ,交付了优质工作。
  • 但状态是 "不妨碍程序员,但也并未真正协作" ——有进步,但还不够。

人事变动

  • 另一位技术美术总监 Andrew Maximov 离职创业。
  • 演讲者接管了其大量 工具与管线(Tools & Pipeline) 方面的职责。
  • 招入 Steven Tang 继续推进着色器开发。
    • 入职后数月进行 持续的代码审查(Code Review) ,将其提升到团队已达到的 代码质量与研究标准 。

逆反射眼睛技术(Retro-Reflective Eyes)

  • 游戏中需要制作 标本狼的逆反射眼睛 ——许多夜行动物具有此特征,好的标本师也会重现这一效果。
  • 人类眼睛着色器已基本完成,因此将此任务交给 Steven 作为 首个独立开发项目 。

动物眼睛的逆反射(Retro-Reflective Animal Eyes)


需求背景

  • 游戏中某些场景(如博物馆)需要动物眼睛在强光下 发出诡异的光芒 ,营造恐怖氛围。
  • 最直觉的做法 :给眼睛加一个 自发光分量(Emissive) ,用菲涅尔调制并绑定到手电筒强度上——但这 非常 Hack 。

科学原理

  • 某些动物(如 狼、猫 )在视网膜后方有一层额外的反射层,称为 脉络膜反光层(Tapetum Lucidum) 。
  • 该层将光线 沿原路反射回去 ,使光线 两次穿过视网膜 ,从而在暗环境中获得更好的视力。
  • 我们看到的"发光眼"效果,本质上就是该反光层的 高光响应(Specular Response) 。

实现方案

  • 理解了物理本质后,实现变得非常简单:
    • 添加一个 高光分量 ,使用 光源方向作为法线 (模拟逆反射——光沿入射方向反射回来)。
    • 用 虹膜区域遮罩(Iris Mask) 限制范围。
    • 对照参考照片进行 调优 。
  • 还叠加了 虹彩效果(Iridescence) ,使用后文介绍的 薄膜干涉(Thin Film Interference) 函数实现。

后续推广

  • 团队非常喜欢这种诡异的发光效果,最终将其 扩展到所有感染者敌人 身上。
  • 眼睛着色器在项目后期持续进行 微调 (如深棕色虹膜上焦散不够强等),但 核心技术一直稳定到项目结束 。

玻璃渲染技术(Glass Rendering)


概述

  • 《最后生还者 Part II》中有 大量玻璃 ,形态各异。
  • 核心策略:将技术做得 模块化、可复用 ,驱动游戏中所有玻璃需求。

四种核心玻璃渲染技术

预乘 Alpha(Pre-Multiplied Alpha)——继承自《神秘海域4》

  • 高光分量始终 100% 存在 。
  • 漫反射不透明度(Diffuse Opacity) 是可变的,用于表现玻璃上的 污垢、油漆 等。

屏幕空间折射(Screen Space Refraction)——继承自《神秘海域4》

  • 使用 扭曲的 UV 坐标 采样屏幕缓冲区的扭曲版本。
  • 扭曲程度由 玻璃的物理属性 决定。
  • 适合 玻璃瓶 等物体。

模糊折射(Blurry Refraction)——新技术

  • 在由 玻璃表面粗糙度 定义的锥体范围内,对屏幕缓冲区进行 时间抖动的多重采样(Temporally Jittered Multi-Sampling) 。
  • 非常适合 毛玻璃/雾面玻璃 效果。
  • 由 程序员 实现。

假室内空间(Fake Interiors)——新技术

  • 大量建筑有 可见的室内空间 ,如果真正建模代价巨大。
  • 解决方案:基于 单个四边形(Single Quad) 用着色器模拟完整的窗户与室内。

假室内空间系统(Fake Interior System)详解

单个 Quad 包含的内容

  • 以下所有元素 全部在一个着色器中完成 :
    • 百叶窗(Blinds)
    • 后方房间 的视差深度
    • 玻璃表面
    • 破碎区域

技术组成

组件实现方式
视差百叶窗在玻璃后方 5–10 cm 处添加即时深度层
室内空间使用 立方体贴图(Cube Map) 表示,灵感来自 Joost van Dongen 的 Interior Mapping 技术
屏幕空间阴影裂纹玻璃的投射阴影
双法线系统高光法线 用于玻璃表面,漫反射法线 用于百叶窗——比单法线效果好得多,比双通道光照计算便宜得多

立方体贴图生成

  1. 美术在引擎中 建模真实的室内场景 。
  2. 灯光师用 中性白光 通过 假窗口开口 照亮场景。
  3. 使用标准的 Cube Map 捕获管线 生成图像。

投影算法

  • 与标准 Box Projection(用于 IBL 立方体贴图光照)原理类似。
  • 关键改进:投影 完全基于几何体的 UV ,而非着色器内参数。
    • 给予美术 极大的灵活性 ——可以自由调整室内空间的位置与缩放。
    • 通过将控制绑定到几何体而非着色器,允许 同一场景中大量变化 。

渲染管线集成

  • 窗户采用 延迟渲染(Deferred Rendered) ,尽可能 低开销 。
  • 立方体贴图乘以 窗户表面上烘焙的环境光照 ,确保光照变化时 无需手动调整能量 。
  • 使用 预乘 Alpha 技术进行混合。
  • 立方体贴图数据 打包进 G-Buffer 的自发光通道(Emissive Channel) 。
  • 完全破碎区域 的 环境光遮蔽设为零 ,这是延迟渲染器中的特殊处理——告知系统 不对这些区域进行高光反射 。
  • 其余一切(粗糙度、高光、漫反射法线等)走 完全标准的渲染管线 。

可交互破碎系统

材质修改缓冲区(Material Modification Buffer)

  • 在 屏幕空间 运作,计算时机在 深度缓冲区之后、G-Buffer 通道之前 。
  • 玩家射击窗户时,生成一个 投射到表面的粒子 ,写入该缓冲区。
  • G-Buffer 通道渲染时读取此缓冲区,决定 哪些区域应破裂 。

低频 + 高频混合策略

频率类型来源
低频信息材质修改缓冲区(射击产生)、美术手绘顶点色(预设破损)、世界空间随机噪声
高频细节仅在低频遮罩的区域内 叠加裂纹细节
  • 该缓冲区最初在《神秘海域4》中开发,在本作中 大幅扩展 了用途。

实际应用效果

  • 在大多数关卡中,假室内效果 非常微妙 。
  • 可以 极其靠近可玩空间使用 ,只要在 近战距离之外 即可。

雨天玻璃效果(Rainy Glass Effects)

效果组成

组件技术作用
屏幕空间折射旧技术(《神秘海域4》)基础静态水滴外观
模糊折射新技术雾面玻璃感
动画雨痕(Rain Streaks)专用 Shader Package修改折射法线与模糊度

雨痕动画纹理通道设计

通道内容行为
R(红)雨痕轨迹将折射模糊度设为 0,遮罩掉静态水滴
G(绿)引领雨痕的大水滴将折射模糊度设为 0,修改折射法线
B(蓝)雨痕留下的静态小水滴不动画,但被 R 通道的雨痕遮罩
A(Alpha)ID 遮罩用于 随机化动画时序
  • 使用 4 个版本 的该纹理 叠加堆叠 ,提供足够覆盖和变化,避免明显的重复图案。

动画实现步骤

  1. 基础滚动 :在 UV 的 V 方向简单滚动。
  2. 速度随机化 :使用 ID 遮罩添加速度变化和时间偏移。
  3. 水平噪声 :添加水平方向扰动,使其看起来像真实雨痕。

时间方差(Time Variance)

  • 水滴不应以 匀速 下落。
  • 使用 单调递增的正弦波噪声 对时间进行扰动:

  • 效果:水滴时快时慢,模拟真实的 表面张力与重力 交互。

破碎玻璃的假厚度效果(Fake Thickness Effect)

实现原理

  • 使用一张 玻璃 ID 遮罩纹理 确定哪些像素属于 截面(Cross-Section) 。
  • 该纹理可在 Substance Designer 中使用 Flood Fill 功能轻松创建。

核心算法

  1. 使用 简单视差偏移(Parallax Offset) 对纹理采样 两次 。
  2. 如果两次采样的值 不同 ,说明视线向量穿过了一个 截面 。

截面着色

组件方法
法线将裂纹纹理的法线贴图进行 膨胀(Dilate) ,作为 漫反射法线 应用;高光法线保持不变 ,保证玻璃表面的连续性
内部反射使用 漫反射法线 采样 环境立方体贴图 ,作为 自发光分量 添加到玻璃上,模拟内部反射

薄膜干涉(Thin Film Interference)

物理原理

  • 常见于带 UV 镀膜 / 防眩光镀膜 的眼镜或相机镜头。
  • 光线击中薄膜表面时:
    • 部分光 从薄膜 顶部反射 。
    • 部分光 折射进入薄膜,从 底部反射 后射出。
  • 两束光线走过 略微不同的路径 ,产生 相位差(Phase Offset) 。
  • 相位差导致 波长相关的干涉 ——不同角度和薄膜厚度下,不同颜色被 增强或抵消 。

其中 为薄膜折射率, 为薄膜厚度, 为折射角, 为波长。

渲染集成

  • 实现为 常规高光计算之后的额外步骤 。
  • 效果 微妙但可见 :在白色光源下,玻璃高光中出现 绿色、紫色 等色调。
  • 同样用于前述动物眼睛的 虹彩效果 。

模块化与统一界面

关键设计原则

  • 所有特殊功能(可破碎玻璃、雨痕、薄膜干涉等)的 界面保持一致 。
  • 不仅适用于各种类型的玻璃,也适用于其他 Alpha 混合表面 (如 植被、头发 )。
  • 一切都 嵌入分层材质框架(Layered Material Framework) :
    • 部分常用功能打包为 Shader Package (如可破碎玻璃包)。
    • 美术仍然可以自由叠加 污垢、湿润、喷漆 等标准图层。

目标达成

在 标准化最复杂的设置 的同时,给予美术 极大的创作自由 。


团队协作的成功体现

玻璃系统的分工

贡献者负责内容
Kov模糊折射
Hawar多层折射技术
Artem & Stephen Marandino玻璃与水的交互
技术美术团队材质系统设计、Shader Package、美术接口

关系修复的里程碑

  • 玻璃系统的开发被视为 程序团队与技术美术团队成功协作 的典范。
  • 成功的关键不仅在于 共同完成的工作 ,还在于技术美术团队 知道何时退后一步 ,为程序员 留出空间直接与美术团队合作 。
  • 演讲者总结:这是一段 漫长的旅程 ——无论是技术层面还是团队关系层面——但 付出完全值得 。

雪地变形系统(Snow Deformation)

这是一个 真正跨学科协作 的范例——技术美术、图形程序员和 VFX 团队共同完成。


系统架构总览

整个雪地变形系统分为三个层次:

层次负责团队核心内容
粒子渲染目标(Particle Render Target)图形程序员检测并记录足迹位置
视差遮蔽映射(Parallax Occlusion Mapping)图形程序员实现几何级别的凹陷变形
细节增强与系统整合技术美术团队法线重建、边缘隆起、阴影、与高度图系统联动

第一层:粒子渲染目标(Particle Render Target)

  • 由图形程序员 Artem Kovalovs 实现。
  • 对每块可变形雪地网格,分配一个 粒子渲染目标区域 (可在场景中看到矩形区域与连接线)。
  • 每帧执行流程:
    1. 从角色 膝盖到脚底稍下方 进行 网格射线检测(Mesh Raycast) 。
    2. 若射线命中雪面,将一个 足迹粒子 绘制到粒子渲染目标中。
  • 渲染目标作为 纹理输入 传递给雪地着色器,告知着色器 在哪里进行变形 。

第二层:视差遮蔽映射变形(Parallax Occlusion Mapping)

  • 由图形程序员 Vincent Markson 与 Artem 等人合作实现。
  • 基本流程:
    1. 在着色器中 采样粒子渲染目标纹理 。
    2. 映射到 世界空间 。
    3. 使用标准 视差遮蔽映射(POM) 实现基础凹陷变形。

深度缓冲修正——关键细节

  • 为了使变形后的表面与其他物体 正确相交 ,POM 必须输出 正确的深度值 。
  • 实现方式:
    1. 计算变形后的 世界空间位置 。
    2. 转换为 屏幕空间深度 。
    3. 在 G-Buffer Pass 之前 ,通过一个 自定义深度像素着色器(Custom Depth Pixel Shader) 将其写入深度缓冲区。

第三层:技术美术团队的细节增强

变形法线重建

  • 使用粒子渲染目标数据,通过 与之前介绍的导数法线相同的算法 构建变形法线:

  • 区别在于:这次计算不是在 屏幕空间 ,而是在 粒子渲染目标空间 中进行。
  • 通过 增大采样间距 ,可以轻松 软化法线 ,避免 棱面化伪影(Faceting Artifacts) 。

边缘隆起效果(Raised Edges)

  • 粒子写入渲染目标时形状为 锥形(Cone Shape) ,直接使用会导致变形看起来不自然。
  • 解决方案:
    1. 使用一个 二次函数(Quadratic Function) 重映射锥形轮廓。
    2. 翻转并镜像 形状。
    3. 最终得到变形周围 平滑自然的隆起边缘 ——模拟雪被挤压后向两侧凸起的真实效果。

变形区域细节法线

  • 使用粒子渲染目标作为 遮罩 ,在变形区域叠加 细节法线贴图 ,增加表面纹理细节。

变形投影阴影(Drop Shadow)

问题

  • 视差效果仅在 G-Buffer Pass 和 自定义深度 Pass 中生效。
  • 当阳光投射阴影时,阴影 Pass 看到的是 未变形的原始雪面 ,导致阴影不正确。

解决方案

  • 完全关闭 雪地几何体的 阴影投射 。
  • 使用基于 太阳方向的视差投影 添加 假阴影(Fake Shadow) 。
  • 坦诚地说:这 仅适用于太阳光 ,但游戏中也确实只有这一种使用场景。

与高度图系统联动

  • 变形区域的 高度图值 会相应更新。
  • 效果:血池贴花只出现在凹陷的足迹内部 ,而非覆盖在未变形的雪面上——与之前介绍的血液-高度图交互系统完美联动。

系统化方法带来的"免费"效果

VFX Lead Evan Cook 说过:"一切都是系统化的(It's all systemic)。"

由于整个系统基于 统一的渲染目标方法 ,以下效果可以 低成本实现 :

  • 变形处 露出雪下的泥土 。
  • 角色在斜坡上滑行时在 泥地中留下痕迹 。
  • 血液融化雪面 的特殊效果。

演讲者强调:"说'免费'当然不完全准确——美术投入了大量心血——但这种方法让实现过程 可行且无痛 ,这就是我们追求的工作方式。"


总结与未来展望


下一代的技术方向

当前成就的意义

  • 这是第一次团队的 许多技术在物理上是正确的 ,可以 直接继承到下一代 ,无需重写。
  • 这意味着团队可以将精力集中在 缺失的细节 上。

仍然缺失的要素

类别示例
缺失的渲染特性桃毛(Peach Fuzz) 、 局部光线弹射(Localized Light Bounce) 、 更精细的头发细节
存在但不够正确的特性毛孔细节不足 、 高光响应不够准确

展望

  • 下一代主机和 PC 的硬件能力将带来 质量的巨大飞跃 。
  • 只要坚持 正确性(Correctness) 和 可复用性(Reusability) ,以及 健康的协作 ,就能充分利用新硬件。

核心哲学总结

基于物理现实,而非堆砌 Hack

"Recreate physical phenomena, don't just layer hacks."

  • 优先级排列 :
    1. 最佳 :如果有真实公式(如 斯涅尔定律 / Snell's Law 用于折射),直接实现。
    2. 次优 :如果真实公式太贵,建立 Ground Truth ,用更廉价的函数 拟合(Fit) 。
    3. 底线 :视觉上对照 自己拍摄的参考 调优——绝不凭空编造。

系统化思维与良好代码

  • 不要只盯着眼前的问题,要思考如何创建 互相构建、互相通信 的可靠且可扩展的 系统 。
  • 美术界面要尽可能 简洁且强大 。
  • 性能优化 不言而喻,必须贯穿始终。

提升团队,做桥梁而非墙壁

"Don't be a wall, be a bridge."

  • 不要替美术与程序员对话 ——把他们直接联系在一起。
  • 不要替程序员向美术团队解释功能 ——让程序员自己展示。
  • 帮助每个人以 最佳方式展示自己的工作 。

Naughty Dog 技术美术团队概况

指标数据
全职技术美术约 8 人
偶尔贡献代码的人员约 12 人
着色器代码量48,000 行
脚本代码量500,000 行

团队职责范围

  • 帧率与内存优化
  • 美术创作标准与规范 的制定
  • 大量工具与脚本 的开发,简化美术工作流
  • 支撑整个渲染管线的材质与着色器系统

致谢要点

  • 图形程序团队 :提供了坚实的引擎基础,技术美术的工作本质上是在此基础上 添加额外细节 。
  • VFX 团队 :许多效果的实现离不开他们的协作。
  • 美术团队 :他们的创意 启发了大量功能 ,并将技术 转化为最终的游戏现实 。