在上一篇文章中,小编为您详细介绍了关于《完美世界鲁晓寅:创新驱动游戏发展,打造中国的“世界名片”》相关知识。本篇中小编将再为您讲解标题如何在 UE4 移动端中实现 HZB?。
|
Hierarchical Z-Buffering 分层 Z 缓冲(HZB)对遮挡剔除研究具有重要影响,是 GPU Driven Rendering Pipeline 的重要剔除手段。目前部分主流商业引擎可能因为某些原因导致该技术无法完全在 GPU 端工作,但依然是值得探讨的。本文先介绍 HZB 的基本原理以及 UE4 在 PC 端的实现方式,然后介绍如何移植到移动端并分析其性能和带来的价值,以及未来还可以做的工作。 HZB 的原理 一般来说,大多数基于 HZB 的遮挡剔除是这样的工作的: 1. 使用一些遮挡器生成一个完整的分层 Z-金字塔。
z-pyramid 的最低级别是一个标准的 z-buffer。在所有其他层,每个 z 值都是上一层对应的 2×2 像素中最远的 z。
2. 要测试的对象是否被遮挡,可以将其包围体投射到屏幕空间,并在 z-pyramid 中估计 mip 级别。将对象的包围体投影到屏幕空间。最长的边 l(像素)用来计算 mip 等级λ。
边长越长,选取的 mip 等级越高。
3. 根据选定的 mip 测试遮挡。如果结果不明确,可以继续使用更细的 mip 级别进行测试。 这个选择的原因是它使成本可预测——最多需要读取和测试四个深度值。此外,这种测试可以被看作是“概率性的”,因为大对象比小对象更容易被看到,所以在这些情况下没有理由读取更多的深度值,即节省了带宽,也增加了 Cache 命中。 UE4 的实现 UE4 只在 PC 端进行了实现,过程大致一样,不同的是在构建层级 Z 缓冲上分为 ComputeShader 和 PixelShader 两种方式,然后最终剔除工作主要在 CPU 端进行,意味着需要回读 GPU 的测试结果。以下是 UE4 的工作流程: 使用 SceneDepth 作为数据源构建层级 Z 缓冲。Mip0 为第一级,大小为 1024*512,总共构建 10 级。分为两种方式,PixelShader 方式比较简单,一次构建一级,总共执行十次。ComputeShader 则稍微复杂一点,利用 GroupMemoryBarrierWithGroupSync,每次同时构建 4 级,总共只要执行 3 次,便完成构建。 场景中的物体经过视锥剔除以后,剩下的会被收集起来,存放在一个数组中,并且每个物体会保存自己在数组中的索引值。然后,创建 2 张 RGBA32 格式的贴图,一张存放物体包围盒的质心坐标,一张存放物体包围盒的大小。每次从数组中取 64 个物体作为一组,保存到贴图的 64 个像素区域中。 采样第二步中的贴图,获取物体的质心坐标和包围盒大小,可以计算出物体包围盒的八个顶点的世界位置,对这八个顶点进行投影,选取其中最近的 Z 值。根据投影后的矩形区域,选取最长边长计算 mipmap 等级,然后在矩形区域内采样该 mipmap 的 16 个像素,选取其中最远的 Z 值。如果包围盒最近的 Z 值比它还小,则物体不可见。将结果保存到一张格式为 RGBA8 的 RenderTarget 中,作为下一帧读取。 当前帧读取上一帧的贴图数据到一个数组中。每个物体将上一帧保存的数组索引到该数据进行查询,查询结果决定了该物体在当前帧的可见性。 以上步骤看出,UE4 的 HZB 实现流程没有完全放在 GPU 端执行,在下一帧的时候需要回读上一帧的结果,然后进行查询以决定物体当前帧的可见性。另外,在第三步中,计算最远 Z 值时,采样了矩形区域内 16 个像素,而不是 4 个像素。 移动端的实现 移动端的 HZB 方案大部分可以与 PC 端共用一套逻辑实现,然后针对移动端性能点进行优化。移动端需要解决的第一个首要问题就是 SceneDepth 的获取,因为它是构建层级 Z 缓冲的重要数据来源。 在移动端上,一般来说,如果存在后处理材质需要访问场景深度信息,UE4 会将场景线性深度值保存在 SceneColor 的 Alpha 通道。而对于透明材质,如果使用了 DepthFade 材质节点,则会通过移动设备扩展 API 来直接提取 FrameBuffer 中的深度信息。 那我们如果想在移动端上直接访问深度纹理的话,需要怎么做了?可以通过设置 r.Mobile.ForceDepthResolve 为 1 来始终保留移动端的深度信息。强制深度解析,为设备保留深度纹理。 移动端获取深度纹理
获取了深度纹理,就可以开始构建层级 Z 缓冲。考虑到移动设备的兼容性,这里只使用了 PixelShader 方式,依然构建了 10 级 mipmap。为了保证深度值的精度,这里将每个深度值编码到 rgba8888 格式的贴图中。 移动端构建层级 Z 缓冲
构建完层级 Z 缓冲以后,接下来就是进行遮挡测试。算法沿用了 PC 端的方式,将结果保存在贴图中,下一帧回读。移动端上回读 GPU 贴图数据,需要注意的是,UE4 会默认处理上下翻转。因为这里只是存放遮挡结果的数据贴图,所以不需要做上下翻转。
最后一步遮挡查询,过程和 PC 端一样,每个物体用上一帧的数组索引去查询自己当前帧的可见性。 优化读取性能 移动端回读 GPU 数据相当耗费性能,我们可以来看下 glReadPixels 分别在 oppo 手机型号为 r15 和 r17 上的测试结果: r15 耗时 6~8ms
r17 耗时 16~20ms
直接调用 glReadPixels 相当慢,不过,好在目前大多数移动设备的 opengles 已经达到 3.0 以上,所以,可以考虑使用 PBO 的方式进行优化,使用 glMapBufferRang 进行读取。过程大致如下: 初始化 2 个 buffer。 buffer1 用于异步 glReadPixels 读取,buffer2 用于 glMapBufferRange 读取。 下一帧交换 buffer,buffer1 用于 glMapBufferRange,buffer2 用于 glReadPixels。
再来看下,优化后的测试结果: 优化后,r15 耗时 0.9ms
优化后,r17 耗时 4~6ms
硬件遮挡查询 和 HZB 在 oppo r15 上的性能对比 经过初步优化,我们来看下,硬件遮挡查询和 HZB 各自在手机上的性能对比。测试分为静态物体和动态物体。新建一个场景,场景内随机生成 10000 个物体。在分别只开启硬件查询和只开启 HZB 的情况下,对帧率和被遮挡物数量的影响。UE4 针对硬件查询做了 Batch 优化,这样可以大大降低硬件查询带来的 DC 开销,不过 Batch 只对静态物体有效。所以,需要分开测试。 动态物体: 如图,只开启了硬件查询,因为动态物体无法 Batch,Occlusion queries 相当高,达到 987,而 draw call 数量达到了 1450。被遮挡物体为 579,可见物体为 411。帧率只有 18。由此可见,对于大量动态物体,硬件查询本身带来了巨大的 DC 开销。
如图,只开启了 HZB,硬件查询的 DC 开销已经没有了,被遮挡物体为 570,可见物体为 420。Draw call 为 467,帧率为 30。
结论:对于大量动态物体查询的场景,从被遮挡物体数量和可见物体数量两个数据指标来看,硬件查询和 HZB 不相上下。性能上,HZB 优势明显。 静态物体: 如图,只开启硬件查询,因为静态物体的原因,硬件查询发挥了 Batch 的优势,Occlusion queries 只有 58,draw call 只有 511,帧率达到 35。
如图,只开启了 HZB,硬件查询 Batch 带来的 DC 也没有了,所以 draw call 略有下降。帧率为 33。
结论:对于大量静态物体查询的场景,HZB 仍适用,性能与硬件查询 Batch 相当。 硬件遮挡查询 和 HZB 在 oppo r17 上的性能对比 同样分别测试动态物体和静态物体,r17 和 r15 表现了完全的不一样的结果,之前在优化读取时也发现,r17 依然有 4~6ms 的开销,这是为什么了?这跟 r15 和 r17 在硬件上不同有关。 R15 硬件参数
R17 硬件参数
另外,值得一提的是,UE4 针对高通设备,做了硬件查询的上限限制。最大 510 次查询,而其他设备默认是最大 4000 次查询。
这导致了 R17 在大量动态物体场景下,即便没有做 Batch,也只有不超过 250 的 Occlusion queries 数量。这并不是什么优化,而是 UE4 直接放弃了超过该数量的硬件查询,再加上依然存在的回读耗时,这样使得 HZB 的优势就不那么明显了。 如图,R17 上,开启硬件查询,关闭 HZB。
如图,R17 上,关闭硬件查询,开启 HZB。
结论:基于以上原因,在大量动态物体和静态物体场景下,HZB 在 R17 上都表现不佳。 其他性能开销 移动端除了回读耗时以外,在 HZB 构建以及遮挡测试阶段,性能消耗也不能忽视,特别是采样 16 次贴图的操作。如下分别是在 R15 和 R17 上的测试结果: R15 在构建和测试阶段分别耗时 2.6ms 和 1.6ms。回读耗时 0.9ms
R17 在构建和测试阶段分别耗时 0.48ms 和 0.41ms。回读耗时 5.2ms
通过对比发现,R15 回读快,而构建慢。R17 回读慢,而构建快。不同的硬件架构带来的性能差异很大,关于移动硬件分析已经不属于本文探讨范畴了,在这里就不展开讲了。 总结 关于 UE 硬件查询的 Batch 结论: 动态物体不会做 Batch,全部一个一个去查询,带来巨大的 DC 开销。 静态物体在被遮挡的情况下会做 batch 查询,DC 显著减少。 高通手机最大查询次数为 510,其他为 4000,而实际推荐最佳查询次数是 250,2000(分别除了 2)。 移动端 HZB 结论: 大量动态物体查询,HZB 适用于非高通移动设备上。 大量静态物体查询,HZB 仍适用于非高通移动设备上,性能与硬件查询 Batch 相当。 针对移动端未来可以做的优化方案: 将物体数据由质心坐标+包围盒范围改为质心坐标+包围球半径,可节省一张 RGBA32 贴图。 将 16 次采样改为采样包围球表面最近点和包围盒四个顶点,可减少 11 次采样。甚至更保守点,直接将包围球面最近点作为采样点进行比较。 高通设备可以考虑使用 vulkan 图形 API 进行数据回读。 高通设备在构建 HZB 的时候可以考虑使用 ComputeShader。 来源:GWB-腾讯创意游戏合作计划 |
编后语:关于《如何在 UE4 移动端中实现 HZB?》关于知识就介绍到这里,希望本站内容能让您有所收获,如有疑问可跟帖留言,值班小编第一时间回复。 下一篇内容是有关《天美动画师实例讲解:如何才能画好一团火焰?》,感兴趣的同学可以点击进去看看。
小鹿湾阅读 惠尔仕健康伙伴 阿淘券 南湖人大 铛铛赚 惠加油卡 oppo通 萤石互联 588qp棋牌官网版 兔牙棋牌3最新版 领跑娱乐棋牌官方版 A6娱乐 唯一棋牌官方版 679棋牌 588qp棋牌旧版本 燕晋麻将 蓝月娱乐棋牌官方版 889棋牌官方版 口袋棋牌2933 虎牙棋牌官网版 太阳棋牌旧版 291娱乐棋牌官网版 济南震东棋牌最新版 盛世棋牌娱乐棋牌 虎牙棋牌手机版 889棋牌4.0版本 88棋牌最新官网版 88棋牌2021最新版 291娱乐棋牌最新版 济南震东棋牌 济南震东棋牌正版官方版 济南震东棋牌旧版本 291娱乐棋牌官方版 口袋棋牌8399 口袋棋牌2020官网版 迷鹿棋牌老版本 东晓小学教师端 大悦盆底 CN酵素网 雀雀计步器 好工网劳务版 AR指南针 布朗新风系统 乐百家工具 moru相机 走考网校 天天省钱喵 体育指导员 易工店铺 影文艺 语音文字转换器