MAKE · WRITE · SHARE

Base-资源流式加载与预算管理

流式加载不是“异步读取文件”的另一种叫法。它是一套根据当前与未来需求,持续决定加载、保留、替换和释放哪些数据的资源管理机制。

Texture Mip、Mesh LOD 与子关卡可以有不同粒度,但共同面对需求预测、容量限制和加载延迟。一个稳定系统既要节约内存,也要避免资源到达太晚或反复进出。

理想需求经过预算约束转为驻留计划,并由异步完成状态反馈

1. 理想需求与实际驻留分开

理想需求由视图、距离、屏幕占比和玩法决定。例如一张纹理理想上需要第 0 到第 4 级 Mip,但实际预算只允许从第 2 级开始驻留。

“想要什么”和“现在能放什么”应是两个状态,便于调试不足来自需求计算还是预算分配。把资源一次性加载进内存后再异步解压,并不自动构成完整的 Streaming 策略。

2. 不可见不等于不需要

相机后方的资源可能很快转到前面,阴影和反射视图也可能使用主视图之外的对象。仅按当前可见性立即卸载,会在转身时造成缺失或抖动。

可以结合预取范围、历史需求和玩法路径,给资源保留时间。预测不可能完全准确,因此系统还需要粗层回退和明确的优先级。

3. 预算池怎样参与决策

1
2
收集需求 → 估计理想质量 → 按预算降级/排序
→ 发出加载与卸载请求 → 完成后切换驻留状态

预算不只包括常驻显存,还包括 CPU 内存、解压临时空间、IO、上传量与每帧提交时间。若只盯着最终驻留,加载峰值仍可能超限。

资源也不应刚好离开需求阈值就卸载。使用滞回、冷却时间或最近使用记录,可以减少反复加载;代价是多保留一部分容量。

4. 异步不代表没有成本

后台读取避免主线程直接等待磁盘,但解压、创建 GPU 资源和上传仍然要占用执行时间与带宽。过多并发请求还可能竞争 IO 和临时内存。

资源准备好后,需要在安全时间切换句柄,并延迟释放仍被 GPU 使用的旧资源。用 Fence 或引擎资源生命周期机制确认完成,而不是 CPU 认为“不用了”就立即回收。

5. Texture、Mesh 和 Level 的差别

纹理可以逐级提高细节;网格可能切换整级 LOD,也可能使用更细的分块;子关卡还牵涉对象、脚本、碰撞和导航初始化。它们不能共享一套未经区分的完成条件。

LOD 也不一定采用流式存储:所有级别都已经驻留时,切换只减少绘制细节,不减少常驻资源。反过来,页面流送未必暴露给美术一个传统 LOD 开关。

6. 如何判断系统是否稳定

使用固定相机路径观察驻留量、请求积压、加载延迟、上传峰值和质量收敛。再加入快速转身、瞬移、场景切换与低预算,检查最差情况。

频繁在清晰与模糊之间跳动,可能是预算不足或优先级抖动;进入场景的尖峰可能来自资源创建,而非文件读取。应让每个阶段都有可观测状态。

总结

Streaming 把“理想画面”转成“受预算约束的驻留计划”。可靠的系统需要预测、回退和生命周期管理,性能收益则来自减少不必要的常驻与传输,而不是把同样的工作换到后台就消失了。

参考资料