UE4-GPUScene
UE4里GPUScene相关的梳理。
1. 引擎传输Primitive数据到GPU的方式
什么是PrimitiveData?
PrimitiveData是UPrimitiveComponent级别的几何数据,包括LocalToWorldMatrix,WorldPosition,AABB,LightMap等数据。

传统方式
每个Primitive一个UniformBuffer,每次DrawCall绑定。
1 | |
上面是概念性路径:UniformBuffer 的创建、更新和绑定是不同操作,缓存策略可能避免每帧重建。不能仅由 DrawCall 数推断每帧上传字节。
简化成本模型:逐 Draw/Primitive 的数据准备与绑定。真实上传量应通过资源更新路径与抓帧核对。
传统绑定仍可以缓存不变数据。GPUScene 的价值还包括统一索引和减少逐 Draw 状态,而不是证明所有传统静态数据每帧都一定完整重传。
GPUScene的方式
UE4 的 GPUScene 路径将 Primitive 参数集中组织,减少逐 Draw 参数绑定,并为按 PrimitiveId 查询数据提供基础。具体可用平台和更新路径以引擎分支为准。
所有的Primitive数据,打包进一个大的StructuredBuffer,GPU里通过PrimitiveId获取。
然后每一帧不变的静态物体的数据就保持不变,只更新变化的静态物体以及动态物体。
动态物体也分为每个视图(不是全部更新),视图会提前收集到需要更新的动态物体。
在原研究分支中,可用“变化的静态 Primitive + 各 View 收集的动态数据”理解更新来源;不是跨版本固定字节公式。

2. GPUScene的工作流程
GPUScene是一个大的功能,它是Primitive基础数据的容器,有一些功能比如DistanceField、LightMap、InstanceCulling这些,有自己的更新逻辑。
如距离场数据的更新,以前在这里写过
UE4-HISM剔除更新DFShadowGPUScene基础的更新流程
标脏 → 收集 Dirty Primitive → 构建 PrimitiveShaderData → 批量写入 StructuredBuffer → Shader 通过 PrimitiveId 读取
更新标记Dirty路径:GameThread——>RenderThread
1 | |
GPU更新流程:
1 | |
多视图共享上传的旧研究
原笔记另记录了对多个阴影视图重复上传动态 Primitive 数据的优化:若同一数据版本已经上传,可以让多个视图引用共享记录,减少重复写入。笔记参考了内部技术文章,不能把参考方案全部视为自研成果。
共享的前提是记录确实与 View 无关。视图相关参数、动态 ID 范围、Buffer 生命周期、并发提交与脏标记都需正确处理。主相机和阴影相机不能仅因指向同一个组件就无条件共享所有数据。
旧记录中的 r.GPUScene.UseViewShareBuffer 属于研究分支开关,不应当作 UE4 官方通用变量。其测试收益依动态对象和视图数量而变;当前没有重新取得原构建和可复现抓帧,因此不补写性能数字。

原笔记配图:多 View 情况下观察重复上传工作的抓帧参考。

原笔记配图:旧测试场景的第一张统计截图;条件来自原记录,不作为本次重新测得的结果。

原笔记配图:旧测试场景的第二张统计截图;截图本身不足以独立证明可迁移的性能收益。
总结
GPUScene 改变数据组织与绑定方式,增量更新避免重复工作;多 View 共享则需要进一步证明数据和生命周期相容。示意调用链用于定位方向,函数签名应回到实际源码分支核对。