UE4 PSO介绍四:PSO Precache

前言

如果你的项目团队不大,没有时间精力去做 "跑测→收集.rec.upipelinecache→再打包"这一套(Bundled PSO Cache),那么 PSO Precache 是一个开箱即用的UE4/5自带的功能。

Precache的"Pre"体现在哪

起初我听到有的游戏"按需"地去缓存PSO,我就不理解precache这种方法哪里有体现"预测",似乎就是即刻按需编译PSO。这是一个误解。

那么所谓的"预测"(Pre)是什么意思呢?主要体现在将原本在游戏运行时(in-game / runtime中的玩家游玩时刻)进行的耗时操作,提前到资源加载阶段完成(in-game / runtime 中的loading时刻),从而避免在实时渲染帧中因编译管线状态对象(PSO)而导致的卡顿(Hitch)。如下图所示,注意下图都是 runtime中,且区分了"绘制时"与"加载时"。

"预先"的具体体现是在:

  1. 时机前置:在绘制发生之前

    如时序图所示,传统的即时编译模式下,PSO的创建和编译是在渲染线程发出具体绘制指令(DrawCall)的瞬间才触发的,这会导致渲染线程必须等待编译完成,造成帧率下降。而PSO预缓存机制将这项工作转移到了资源加载阶段(例如关卡加载界面或对象流送时)。系统在加载网格体、材质等资源时,就会自动分析并触发其可能需要的PSO的编译任务,远早于这些资源被实际渲染到屏幕上的时刻。

  2. 预测性准备:分析而非响应

    "预先"还体现在系统的预测行为 上。当一个静态网格体组件被加载时,其 PostLoad函数会被调用。在这个过程中,预缓存系统会分析该网格体的顶点工厂信息、其上附着的材质在所有画质等级下可能产生的着色器变体,以及它可能参与的所有渲染通道(如深度预填充、主渲染、阴影生成等)。系统会基于这些信息,计算出一个需要为该网格体预编译的PSO列表,而不是等到相机看到它时才去准备。

  3. 异步编译:不阻塞主线程

    这个预测和编译过程是在后台异步 完成的。这意味着,即使在加载界面需要编译成千上万个PSO,也不会阻塞游戏主线程的运行。玩家可能感受到的是加载时间变长,但进入游戏后,由于大部分PSO已经准备就绪,游戏过程的流畅度会得到极大保障。这实现了将不可预测的运行时卡顿 转换为可预测的加载时间等待的优化目标。

总而言之,PSO预缓存中的"预先",其精妙之处在于主动规划、提前准备。它将一个高延迟的、破坏性的操作从关键的实时渲染路径中移除,通过利用加载阶段相对"空闲"的时间来预先支付渲染成本,从而为玩家提供稳定流畅的帧率体验。这是一种典型的用空间(内存、加载时间)换取时间(运行时性能)的优化策略。

理解UE4中"开箱即用"的PSO Precache默认策略非常重要,它能帮助您建立优化的基础。简单来说,如果您不进行任何自定义配置,UE4的PSO Precache会尝试以一种**"尽力而为"的自动化模式** 工作,其核心目标是在资源加载阶段,预测并提前编译游戏可能需要的PSO,从而避免这些编译操作在游戏运行时(渲染帧中)发生,导致卡顿

下面这个表格详细梳理了PSO Precache的默认工作策略。

核心方面 "开箱即用"的默认策略
触发时机 在网格体组件(如UStaticMeshComponent, USkeletalMeshComponent)被加载、调用其PostLoad()函数时自动触发。
预测逻辑 系统会分析该网格体所关联的材质 和其顶点工厂 ,并结合当前的画质等级等全局渲染状态,计算出一系列可能用于渲染该网格体的PSO组合。
工作方式 预测出的PSO编译任务会被提交到后台异步线程执行,以避免阻塞主线程和渲染线程。
缓存机制 编译好的PSO会缓存在内存中。同时,现代图形API的驱动程序也会在磁盘上维护一个缓存,游戏第二次运行时加载速度会大大加快。
核心目标 将PSO编译的耗时操作从实时的游戏渲染帧 中转移至资源加载阶段,用可能稍长的加载时间来换取游戏过程的极度流畅。

💡 默认策略的潜在局限

虽然开箱即用非常方便,但了解其局限性对项目优化至关重要。默认策略主要依赖于对已加载的静态资源和当前渲染设置的分析,这可能导致以下几种情况:

  1. 预测可能过宽:系统为了确保覆盖率,可能会预测并编译一些在实际游戏中根本不会用到的PSO组合。例如,同一个材质在不同画质设置下会产生变体,默认策略可能会为所有可能的画质等级都编译PSO,即使玩家只会使用其中一种。这会造成额外的内存和CPU时间开销。

  2. 对动态内容覆盖不足 :这是默认策略的主要盲区。对于在游戏运行时通过代码或蓝图动态生成 的Actor,或者材质在运行时发生动态切换的情况,PSO Precache系统在资源加载阶段无法预知这些变化。因此,这些动态对象所需的PSO将无法被预缓存,只能在首次使用时实时编译,引起卡顿。

  3. 移动平台性能考量:在移动设备上,CPU核心数和性能通常弱于PC。虽然PSO Precache同样适用,但更长的编译时间可能带来挑战。UE4可能会针对移动平台调整策略,例如跳过一些不常用的渲染状态组合来减少预缓存集的大小,但这可能会增加渲染罕见状态时出现卡顿的风险。

🛠️ 检查与优化建议

为了确保PSO Precache达到最佳效果,您可以进行以下检查和优化:

  • 验证预缓存效果 :在非开发版游戏启动时加入命令行参数 -clearPSODriverCache,可以模拟玩家首次运行或更新显卡驱动后的环境。同时,在控制台使用 stat PSOPrecache命令可以查看预缓存的统计信息,帮助您了解命中与缺失情况。

  • 考虑混合方案 :对于内容相对固定、流程线性的游戏部分,可以继续使用Bundle PSO Cache。通过自动化测试收集PSO使用记录,生成一个高质量的预缓存文件并打包进游戏。然后,可以让PSO Precache作为补充,处理那些无法被Bundle Cache覆盖的边缘情况或动态内容。

  • 管理加载预期 :由于PSO Precache将编译工作转移到了加载阶段,关卡初始化时间可能会显著变长。设计清晰的加载界面和提示,管理好玩家的等待预期,是提升体验的重要一环。

希望这些信息能帮助您全面了解UE4中PSO Precache的默认策略。如果您对如何针对您的特定项目进行更深入的优化配置(例如使用Usage Mask)感兴趣,我们可以继续探讨。

相关推荐
小江村儿的文杰1 天前
UE4 PSO介绍三:认识.scl.csv
ue4
小江村儿的文杰2 天前
UE4 PSO介绍二:认识.rec.upipelinecache
ue4·pso
小江村儿的文杰2 天前
UE4 PSO介绍一:PSO的定义(编辑中)
ue4·pso
njsgcs3 天前
ue4 我的ai要用到的一下方法汇总 + ue的ai编程助手
ue4
神米米3 天前
Maya快速安装UE4 布料权重绘制插件PhysX导出apx
游戏引擎·ue4·maya
njsgcs3 天前
ue4 开放exec接口 vscode mcp铺垫 unreal.register_slate_post_tick_callback
ide·vscode·ue4
每天回答3个问题3 天前
Lua 函数教程
开发语言·ue5·ue4·lua
每天回答3个问题4 天前
Lua Table(表)
开发语言·ue4·lua·虚幻引擎
小江村儿的文杰5 天前
UE4 Cook流程中IdenticalUncookedPackages的含义,以及一种“资源未打包”情形的解释
ue4·cook