从首次启动着色器卡顿 到 高级着色器分发 ASD

张开发
2026/4/3 23:14:19 15 分钟阅读
从首次启动着色器卡顿 到 高级着色器分发 ASD
一、着色器卡顿的根源回顾为什么首次加载这么慢1. 着色器GPU 的可编程核心什么是着色器在早期的固定功能管线时代GPU 只能按照预设的流程处理顶点和像素。如今GPU 是可编程的。着色器本质上是一段运行在 GPU 上的小程序。它负责告诉 GPU 如何渲染 3D 世界中的每一个顶点和每一个像素。主要的着色器阶段在现代渲染管线中有几个关键的着色器阶段顶点着色器输入模型顶点的位置、法线、UV 坐标。任务执行坐标变换将模型空间坐标转为屏幕空间坐标。它是“骨架”阶段决定了物体在屏幕上的形状。片段着色器输入顶点着色器插值后的数据。任务计算每个像素的最终颜色。性能关键这是 GPU 执行最频繁的阶段。你看到的“光影、材质、反射”几乎都写在这里。计算着色器任务不负责渲染而是利用 GPU 进行通用计算如物理模拟、粒子系统、后处理特效。为什么不能直接运行着色器通常由高级语言HLSL/GLSL编写必须转换为 GPU 硬件能理解的机器码才能执行。2. 编译从源代码到机器码离线编译AOT在开发阶段使用特定 GPU 架构的编译器将着色器编译为二进制机器码直接打包进游戏。优点是无运行时开销缺点是二进制体积大、无法覆盖所有硬件。说人话就是游戏开发者在你下载游戏之前就已经在服务器上用编译工具将着色器代码编译成了 GPU 厂商指定的二进制指令。优点游戏启动时加载即可使用运行丝滑。缺点二进制文件巨大由于 GPU 架构繁多开发者很难针对每一张显卡都准备好最完美的二进制代码。运行时编译JIT游戏只携带中间代码如 DXBC、DXIL或源码在玩家设备上由显卡驱动即时编译。优点是兼容所有 GPU缺点是编译本身消耗 CPU 时间且会阻塞渲染管线。游戏引擎只打包了着色器的中间表示或源代码。当你第一次运行游戏时或者第一次进入某个新地图、第一次释放某个新技能时驱动程序NVIDIA/AMD/Intel负责将这些代码即时编译成当前显卡的机器码。优点文件体积小兼容性极好。缺点卡顿的根源。3. 编译时机决定体验首次启动集中编译游戏在启动时或关卡加载时预先编译所有可能用到的着色器表现为长时间的进度条或加载界面。虽然第一次启动慢但进入游戏后通常不会因编译而卡顿。即时编译Just-in-Time游戏未预先编译所有着色器当渲染管线首次遇到某种材质、特效或场景组合时驱动才临时编译对应的着色器变体。编译期间 CPU 繁忙、GPU 空闲导致单帧耗时从正常的 16ms 暴涨至数百毫秒画面出现明显停顿。这是“着色器卡顿”的最典型表现。4. 主机 vs PC硬件一致性的鸿沟主机PS5 / Xbox Series X|S硬件配置固定GPU 架构、驱动版本、系统环境完全一致。游戏开发者可以在开发阶段使用目标主机的编译器离线编译所有着色器为最终机器码打包进游戏。玩家拿到游戏后无需任何编译因此不存在加载进度条也不存在游戏内卡顿。PC硬件碎片化严重不同厂商NVIDIA / AMD / Intel、不同架构RDNA、Ada Lovelace、Alchemist、不同驱动版本、不同 Windows 更新组合成千上万种。开发者无法为所有可能的配置提前提供离线编译的二进制文件。因此 PC 游戏必须依赖运行时编译 本地缓存的方案。5. 传统 PC 方案的局限运行时编译 本地缓存游戏首次运行时驱动将编译结果存入磁盘缓存下次运行直接复用。但缓存仅对当前硬件/驱动有效更换 GPU 或更新驱动后缓存失效需要重新编译。PSO 缓存Pipeline State Object引擎在加载关卡时提前收集该关卡所有着色器变体并编译将编译开销移至加载界面而非游戏过程中。但如果收集不全如未覆盖所有动态组合仍有遗漏的变体在游戏内触发 JIT 编译导致卡顿。异步编译当需要编译新着色器时先用一个 fallback 着色器如纯色渲染编译完成后替换。这能避免画面停顿但可能出现短暂材质闪烁或显示错误且无法彻底消除延迟。驱动级预缓存NVIDIA / AMD 通过驱动后台下载热门游戏的预编译缓存但覆盖的游戏有限且仍依赖玩家联网和驱动更新。6. 为什么传统方案无法根治卡顿根本原因在于编译工作始终发生在玩家设备上。无论怎么优化时机只要存在“某个着色器变体在游戏运行前未被编译过”就必然在首次使用时产生编译开销从而可能引发卡顿。主机之所以完美是因为它把编译工作完全放在了玩家拿到游戏之前。二、微软 ASD把编译搬到云端1. 核心思想将着色器编译这一昂贵的工作负载从每一台玩家设备转移到云端集中完成然后把编译好的结果随游戏一起分发给玩家。玩家下载游戏时本地已经拥有了针对自己显卡的预编译着色器缓存首次启动无需编译游戏过程中也不会触发即时编译。2. 技术实现微软在 DirectX 层面引入了一套标准化流程State Object Database (SODB)一种标准格式用于收集游戏所需的所有着色器元数据。Precompiled Shader Database (PSDB)在云端结合 SODB 与硬件厂商如 AMD提供的编译器针对特定显卡架构提前编译生成的最终机器码数据库。分发与缓存集成PSDB 通过 Xbox 商店等平台随游戏下载自动存入 Windows 着色器缓存。游戏启动时直接读取跳过编译步骤。若驱动更新导致缓存失效系统会自动重新下载匹配的新缓存。3. 实际效果微软在博客中以《Avowed》为例采用 ASD 后游戏启动时间减少 85%不仅进入游戏更快掌机设备的电池续航也更多用于游玩而非编译。4. 部署路线首发在 ROG Xbox Ally 系列掌机上推出初期无需游戏开发者额外集成。扩展计划发布 Agility SDK提供 API 和工具让更多游戏、商店平台能够原生支持 ASD。三、开发者社区的不同声音ASD 发布后也有开发者提出长期担忧“如果 10 年后微软关闭了存储这些着色器的服务器而游戏完全依赖这项功能就会造成糟糕的体验。正确的做法应该是在 DirectX API 层面修复实现异步编译和分批次编译提示。”这反映了两种思路的分野ASD是一种基于分发渠道的实用方案能立刻改善当下体验。长期理想是让图形 API 自身提供更底层的机制使引擎能优雅处理编译延迟不依赖外部预编译数据。四、总结从理解问题到解决问题把两部分串联起来可以清晰地看到着色器卡顿的本质运行时编译导致渲染管线阻塞。传统解决方案将编译提前到加载阶段或使用缓存但编译仍发生在本地。ASD 的突破彻底改变编译发生的位置——从本地设备移到云端通过预编译结果的分发消除所有玩家端的编译开销。ASD 是图形 API 平台方DirectX、硬件厂商AMD与分发平台Xbox 商店三方协作的成果它不一定能完全替代引擎层面的异步编译等机制但为解决 PC 游戏生态中长期存在的着色器卡顿问题提供了一条立即可行的系统级路径。未来随着 Agility SDK 的普及和更多设备支持ASD 有望让“首次加载慢”和“游戏内卡顿”成为历史——至少在支持该技术的游戏和平台上如此。了解更多游戏引擎与着色器卡顿虚幻引擎对此问题的解决方案——虚幻引擎 --- Game engines and shader stuttering: Unreal Engines solution to the problem - Unreal Engine介绍高级着色器交付——DirectX 开发者博客 --- Introducing Advanced Shader Delivery - DirectX Developer Blog

更多文章