CommandBuffer的GPU开销

CommandBuffer的GPU开销

1)CommandBuffer的GPU开销
2)如何加载Unity打出的OBB分包文件
3)关于LOD的优化顺序
4)场景静态合并如何与LOD共存
5)如何控制单个Renderer的Texture Mipmap等级


这是第153篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)


渲染

Q:在进行后处理方案预研的时候发现,PostProcessV2中使用的CommandBuffer方案,似乎比V1使用Graphics接口的方案需要更多的GPU开销。

测试工程在这里:CBTest.unitypackage

真机测试结果:
在红米2A(低配机)上,使用Graphics.Blit的后处理对帧率几乎没有影响,而开了CommandBuffer,帧率立刻从60拉到了40。

Profiler以后,CommandBuffer.Blit的开销比Graphic.Blit要低(前者0.0x ms,后者1.x ms),但是插了CommandBuffer后Device.Present明显升高。

换了高配机各做100次后处理,得出的结论也是一样的。两种方案使用了相同的Shader,且是简单的颜色计算,应可排除Shader的影响。

想问一下,是否CommandBuffer就是会更耗GPU性能?如果是,这部分开销是在哪里?如果就是有很高的额外开销,那CommandBuffer除了灵活还有哪些优势呢?

A:大概看了一眼,我分析是这样的。这个是因为您用了cmdBuffer.Blit(BuiltinRenderTextureType.CurrentActive, mainTexId);回拷官方版本,人家是直接指针指过去的:cmdBuffer.SetGlobalTexture(mainTexId,BuiltinRenderTextureType.CurrentActive);

题主补充Q:这里又引出了另一个问题,我最开始是尝试使用SetGlobalTexture,

cmdBuffer.SetGlobalTexture(mainTexId, BuiltinRenderTextureType.CameraTarget); 
cmdBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); 
cmdBuffer.DrawMesh(FullscreenTriangle, Matrix4x4.identity, BriMaterial);

Frame Debugger看到传入Shader的是DrawMesh已经画上三角形的图像。猜测这样同时从BackBuffer里面取图像并写入可能会有时序问题,PostProcessV2里因为使用了DrawMesh,其传入的source也是生成的RenderTexture不是BuiltinRenderTextureType.CurrentActive。

A:具体代码我没有进去试验。但是我可以提供两个思路,一个是使用Camera.renderTarget.colorBuffer,这里不一定是Custom RenderTexture的,默认相机的也能拿到(Unity 2019);另一个是采用TAA的思路,把前一帧数据hold住,您可以尝试下。

感谢张言丰@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c90b148276f530b35fdd6de


OBB

Q:Unity官方教程推荐的那个AssetStore上的Google Play OBB Downloader插件,核心函数是用的WWW.LoadFromCacheOrDownload。

在Unity升级到2017版本后,这个函数加载OBB分包会提示解压缩失败。

插件有四年没有更新了,我搜索到也有一些人遇到过这个问题。请问有朋友解决过这个问题吗?

A1:对于Unity直接打出APK+OBB,是没问题的。如果是Unity导出工程+OBB,有的项目可能会因为OBB校验不通过,导致OBB用不了。Unity导出工程的AndroidManifest.xml中有一个meta-data。
请输入图片描述
请输入图片描述
这个value要与OBB解压之后的校验文件对应上,就可以了。
感谢范世青@UWA问答社区提供了回答

A2:遇到过一个安卓的权限bug,你看看是不是这个问题:https://7dot9.com/2017/10/12/google-play-obb-fundamental-pitfall/

没有SD卡读写权限,并且用了OBB,在某些机型上就会出错,重启手机之后能正常启动。

感谢deviljz@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c90efe7276f530b35fdd6e0


LOD

Q:关于LOD的优化顺序。比如:场景、人物、怪物、NPC 这样的优先级顺序是否合理?

A:从渲染面片上来说,通常场景部分的渲染面片数会比较高,很有必要做LOD,其次可以考虑角色部分;而从DrawCall和Overdraw上来说,建议把粒子系统也加入LOD,类似于按高中低的分级,控制特效中激活的粒子系统数,发射粒子数以及粒子的面积大小等。

该回答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c984991419e740b2b8afad6


LOD

Q:场景静态合并如何与 LOD 共存,是否禁用静态合并并使用Mesh Baker手动合并网格与LOD结合?

A:Unity自带的LODGroup和Static Batching是可以同时使用的,只是在开启Lightmap之后可能会有一些问题需要处理,可以参考这个问答中讨论的内容:https://answer.uwa4d.com/question/5ad836acbdcd031091afdb80

该回答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c9849a3419e740b2b8afad7


Mipmap

Q:纹理开启Mipmap之后,感觉有点糊,如何控制单个Renderer的Texture Mipmap等级?

A:控制单个纹理的Mipmap选择确实是有可能的。GPU在对纹理进行采样时,对Mipmap等级的选择可以通过Mipmap Bias来进行修改,关于这个参数具体含义以及使用的限制可见:https://docs.unity3d.com/ScriptReference/Texture-mipMapBias.html,但修改该值有可能会增加GPU的性能开销,所以需要注意。

该回答由UWA回提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c984f69276f530b35fdd960

今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(原群已满员)

封面图:LWRP:优化实时性能(来自网络)