WWDC Quick Look 💓 By SwiftGGTeam
Bringing Cyberpunk 2077 to Mac

Bringing Cyberpunk 2077 to Mac

观看原视频

Highlight

CD PROJEKT RED 分享了将《赛博朋克 2077:终极版》移植到 Apple Silicon Mac 的完整流程,展示了如何使用 Game Porting Toolkit 评估、Metal 渲染管线优化、“For this Mac”预设系统以及平台原生特性(HDR、空间音频)来实现高质量的 macOS 游戏体验。

核心内容

在游戏开发领域,将一款规模如《赛博朋克 2077》的 3A 大作带到新平台,从来不是一件轻松的事。

夜城(Night City)是一个拥有庞大 NPC 流量、实时交通系统、复杂 AI 行为、物理模拟和动态光照的开放世界。所有这些系统在并行运行,对 CPU 和 GPU 都提出了巨大挑战。更不用说游戏还支持光线追踪和路径追踪等高级图形模式。

当 CD PROJEKT RED 决定将游戏带到 Mac 时,他们面临三个核心问题:

  1. 视觉保真度:游戏的霓虹灯光、材质表现、整体氛围是《赛博朋克》的核心身份,不能妥协
  2. 稳定性能:在复杂场景(拥挤街道、高速驾驶、激烈战斗)下需要保持流畅帧率
  3. 原生体验:充分利用 macOS 平台特性,让游戏感觉像是为 Mac 打造的

传统移植方案往往意味着大量试错和漫长的性能调优周期。Apple 的 Game Porting Toolkit 改变了这个游戏规则——它让开发者能够在开始编写任何代码之前,就在 macOS 上评估 Windows 版本的运行情况。

CD PROJEKT RED 用这套工具快速回答了关键问题:在 Mac 上实现目标画质是否可行?性能瓶颈在哪里?应该优先关注哪些领域?

有了这些数据,团队制定了一条清晰的路线图:原生构建、Metal 渲染管线、性能优化,最后是平台特性的整合。

详细内容

Game Porting Toolkit 评估流程

00:50

在开始任何原生开发之前,CD PROJEKT RED 使用 Game Porting Toolkit 在翻译环境中运行 Windows 版本,收集关键数据:

  • 帧时间统计:使用引擎内分析器获取可比较的一致性数据
  • Metal HUD:关联场景事件与追踪数据,识别着色器翻译、加载等事件
  • 引擎内部分析:按线程分解,了解哪些 CPU 系统在何时活跃

评估结果显示,Apple Silicon 上的 GPU 性能超出预期,即使在翻译环境中也能作为基准。CPU 压力是主要挑战,特别是在密集场景中。

两个模式被识别为翻译环境伪影:实时着色器翻译导致的帧时间振荡,以及音频中间件的高占用。这些信息让团队知道在原生实现中需要优先解决什么。

Metal 渲染管线构建

09:39

原生 Metal 渲染管线的构建分为几个阶段:

  1. 单元测试:逐步搭建 Metal 后端,仔细验证基础输出
  2. 静态场景:验证单元测试无法很好覆盖的部分——光照栈、后处理效果、场景级行为
  3. 动态场景:摄像机移动、流式传输、游戏玩法开始暴露真正的边缘情况
  4. 光线追踪和路径追踪:在保持视觉输出一致的同时优化性能

Metal Shader Converter 发挥了重要作用,它让团队能够快速获得广泛的着色器覆盖,渲染有意义的场景。工作流程是一个循环:集成转换器、验证可重复场景、细化不匹配的高级着色器、重复。

MetalFX Upscaling 动态分辨率

12:32

为了在不同 Mac 设备上扩展性能,团队使用了 MetalFX Upscaling:

  • 在较低内部分辨率渲染,在更短时间内重建更高分辨率输出
  • 在重型场景中获得更多性能空间,而不全面降低质量
  • 使用动态分辨率缩放保持负载下的稳定性能
  • 作为时间上采样器,帮助图像在快速移动和 VFX 密集场景中保持稳定

”For this Mac” 预设系统

13:20

这是《赛博朋克 2077》Mac 版的一个核心创新。“For this Mac” 是基于设备的图形预设系统:

  • 检测 Mac 硬件
  • 自动为该设备配置最佳设置
  • 无论使用哪种支持的 Mac,首次启动即可获得稳定、愉快的起点

团队为每台支持的 Mac 设备单独调优设置:

  • 维持图像保真度
  • 目标 FPS 设为 30 或 60
  • MetalFX 与动态分辨率缩放配合使用
  • 调整最小和最大分辨率边界以达到目标 FPS
  • 根据显示器能力启用 HDR
  • 设置 VSync 以实现适当的帧节奏

NSNotification 事件处理

18:43

为了让游戏在系统层面感觉原生,团队响应了多个 NSNotification 事件:

// 检测窗口遮挡状态,决定是否暂停渲染
NSWindowDidChangeOcclusionStateNotification
// 检查 NSWindow.occlusionState

// 响应显示器配置变化
NSApplicationDidChangeScreenParametersNotification
// 获取新屏幕分辨率,更新游戏窗口

// 响应窗口移动到新显示器
NSWindowDidChangeScreenNotification
// 收集新显示器详细信息(Display ID、分辨率、镜像模式、屏幕名称)

// 管理光标切换
NSWindowDidResignKeyNotification → 显示系统光标,隐藏游戏光标
NSWindowDidBecomeKeyNotification → 隐藏系统光标,显示游戏光标

关键点

  • 通过 NSWindowDidChangeOcclusionStateNotification 检测游戏是否在后台,不在可见时不渲染以节省资源
  • 通过 NSApplicationDidChangeScreenParametersNotification 响应显示器设置变化
  • 通过 NSWindowDidResignKeyNotificationNSWindowDidBecomeKeyNotification 管理游戏光标和系统光标的切换

HDR 自动校准

23:10

Apple 的 Extended Dynamic Range (EDR) 管道让游戏能够自动校准 HDR 输出:

// 获取当前显示器的最大 EDR 值
float maxEDR = [NSScreen.mainScreen
    maximumExtendedDynamicRangeColorComponentValue];

// 将该值发送到色调映射器
toneMapper.setMaxHDRValue(maxEDR);

// 检查是否应默认启用 HDR
float potentialEDR = [NSScreen.mainScreen
    maximumPotentialExtendedDynamicRangeColorComponentValue];
if (potentialEDR > 2.0f) {
    // 启用 HDR
    enableHDR();
}

关键点

  • maximumExtendedDynamicRangeColorComponentValue 动态获取当前最大 EDR 值
  • 该值会根据显示器硬件能力和其他条件动态变化
  • 使用此值驱动色调映射器的最大 HDR 输出,始终获得最佳 HDR 渲染
  • 当最大潜在 EDR 值大于 2.0 时,为 XDR 显示器默认启用 HDR

头部追踪空间音频

24:49

通过 Apple 的空间音频 API,游戏为 AirPods 用户启用了头部追踪:

// 启用 AirPods 的头部追踪
AVAudioEnvironmentNode *environmentNode = ...;
environmentNode.listenerHeadTrackingEnabled = YES;

关键点

  • 游戏现有的空间音频支持通过音频中间件实现
  • 音频中间件通过 AVAudioEngine 实现 Apple 空间音频 API
  • 设置 listenerHeadTrackingEnabledtrue 启用头部追踪
  • 默认启用,无需额外设置

核心启发

  1. 使用 Game Porting Toolkit 作为评估工具 在开始任何原生代码之前,先用翻译环境评估你的游戏。它能快速告诉你可行性和性能热点,节省大量试错时间。

  2. 实现 “For this Mac” 式的智能预设 不要让玩家在首次启动时面对复杂的图形设置菜单。检测硬件能力,自动配置最佳预设,提供即开即玩的体验。

  3. 充分利用 EDR 和空间音频 Apple 的 HDR 显示器和空间音频是差异化优势。EDR 自动校准消除了手动校准的繁琐,空间音频增强了沉浸感。这些特性实现成本低,用户体验提升明显。

  4. 响应系统事件 处理 NSNotification 事件让你的游戏在系统层面感觉原生。窗口遮挡、显示器变化、应用切换这些细节的妥善处理,会让玩家感受到精致。

  5. MetalFX 是性能扩展的关键 对于需要在多种硬件配置上运行的游戏,MetalFX Upscaling 和动态分辨率缩放提供了在不牺牲画质太多的情况下获得稳定性能的有效途径。

关联 Session

评论

GitHub Issues · utterances