找回密码
 立即注册
查看: 538|回复: 3

[笔记] Unity上怎么在移动端使用Render pass实现高性能的延迟着色?

[复制链接]
发表于 2021-9-22 07:49 | 显示全部楼层 |阅读模式
Render pass可以实现pixel local storage,大幅降低带宽开销。
发表于 2021-9-22 07:51 | 显示全部楼层
我觉得可能要这样做:
1、在Project Settings中把Graphics API设转置为Vulkan(可能Metal也行,不了解Metal。。)
2、使用Unity提供的Render pass、subpass相关的API(Unity暴露出的Render Pass API简直和Vulkan的原生Renderpass API一毛一样,我贝者一毛钱Unity真“实现(封装)”了Vulkan的RenderPass),进行实现,具体实现原理见下面,可能这篇文章也能参考一下。
(如果图形API设置为OpenGL ES一定是不行的。可能Metal也行,不太了解Metal。)
因为Unity只有在使用Vulkan或Metal时才是真正的natively实现了Render pass,其它API的情况只是模拟"emulation"。
Vulkan 移动端Multipass 延迟渲染相关的Slide:Vulkan Multipass Mobile Deferred Done Right。
这篇2017年的slides中说明了在移动端使用Vulkan API进行“高性能延迟着色”的原理,大致如图1所示(slides截图)。
在桌面GPU上进行延迟渲染(基于MRT),使用了两个渲染passes: G-Buffer pass和Lighting pass。
而这里介绍的在移动端GPU上使用Vulkan进行延迟渲染,实际上是把两个passes合成“一个render pass”了。
实现这一切的前提是Vulkan的一个Render pass可以包含多个Subpasses,利用On Chip SRAM。
更准确地说是,Mobile GPU上做延迟渲染时,让Vulkan的一个render pass包含两个subpasses,第一个subpass完成G-Buffer pass的功能,计算出的数据直接存在于On Chip SRAM上。第二个subpass完成Lighting pass的功能,GPU能直接访问第一个subpass计算出的G-Buffer数据,大大降低了带宽。移动端GPU和CPU是共享的Memory的,而On Chip SRAM是离GPU最“近”的静态随机存取存储器(SRAM),可以理解为GPU从On Chip SRAM上读取数据速度最快(相比于Off Chip Memory,如图3所示),带宽最低。带宽消耗低,当然相应地也能减少电力消耗。
注意:Unity官方文档是这样说的: Render passes are natively implemented on Metal (iOS) and Vulkan, but the API is fully functional on all rendering backends via emulation (using legacy SetRenderTargets calls and reading the current pixel values via texel fetches)
所以,Unity只是在使用Vulkan或Metal API时才真正使用地natively使用了Render passes。而当使OpenGL ES等时,它只是模拟Renderpass,也就没有subpasses,都是只是“模拟”,当然也不能像Vulkan API那样利用On Chip SRAM了。
所以利用Unity提供的关于Render pass,subpass相关的api,并且在Project Setting中把Graphics API设为Vulkan,应该能实现题主说的移动端高性延迟渲染。
(我不太了解Metal,但是它和Vulkan一样都是Modern Graphics API,可能也行)




图1 Vulkan MultipassMobile Deferred Done Right



图2 Baseline Test Data,带宽减少了80%。



图3 On-Chip Memory vs Off-Chip Memory。图片来自:https://link.springer.com/chapter/10.1007/978-1-4615-5107-2_5

参考:
Vulkan Multipass Mobile Deferred Done Right
Unity - Scripting API: Rendering.ScriptableRenderContext.BeginRenderPass (unity3d.com)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-9-22 07:59 | 显示全部楼层
现状:
1、Unity官网说引擎底层通过RenderPass来实现:
Rendering.ScriptableRenderContext.BeginRenderPass
2020.3需要修改URP下的几行代码才能开启延迟,并且根本不是文档里说的高效方式,就是普通的MRT。
2021.2.0b2支持了延迟,创建URP的示例工程,ForwardRenderer里可以打开延迟着色。切换到安卓平台,并选择Vulkan,默认情况下,打包到安卓上GBuffer阶段输出的是MRT,没有用pre pass的方式。GBuffer阶段是在BeginRenderPass/EndRenderPass之间的,累加光照也是在这两者之间,所以根本没有用到BeginSubPass/EndSubPass,还是会浪费GPU的带宽。如果勾选上Native RenderPass,会是高性能模式。将demo里的方向光复制19份,经测试,在三星S7 Edge上会有轻微的性能提升,帧时间从130ms下降到121ms。三星S8+和华为 mate 30 pro上没有明显差别。


但是总觉得Unity上设置的可能还不是完全正确,经过接诊分析,确实。修改了几处,截帧看到确实生效了。回头再详细测试下性能,尤其是针对iPhone。
2、某上线手游说支持了,但也是pre-pass方案,终于解释了我一直以来的一个疑问:为什么手机上运行发烫。
3、UE4已经支持了Render pass方案,移植到Unity里需要修改大量的C++代码。但绝大部分公司没有购买引擎代码,并且版本维护也是个麻烦事。
4、如果官方支持的不好,而项目短期内想用,理论上来说也可以用Native rendering plugin的方式实现。
5、“Native rendering plugin”的实现方案已经花不少时间基本上调研完毕,理论上完全可行。但是最近实在没有多余精力,有感兴趣的朋友可以一起来搞,共享研究成果。个人QQ号:,申请好友时请注明:延迟着色。条件:1、Unity使用经验3年以上;2、有渲染基础;3、每周业余时间至少有15小时。
6、上面的内容大改过2次,每次都修改了严重的错误。两次都是因为道听途说,还是自己亲身验过的最靠谱。向之前被误导的朋友致歉。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-9-22 08:08 | 显示全部楼层
urp12.0利用core rp提供的renderpass api实现了native renderpass功能,即在vulkan下使用subpass input,在metal下使用memory less来实现onchip single-pass deferred shading,可以在renderer asset上激活这个选项
urp的这个实现逻辑冗余非常多,不建议直接使用
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 12:11 , Processed in 0.123992 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表