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 DongenInterior 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 团队 :许多效果的实现离不开他们的协作。
  • 美术团队 :他们的创意 启发了大量功能 ,并将技术 转化为最终的游戏现实