问答 运用 Post Processing 导致帧率明显下降

侑虎科技 · 2020年09月23日 · 1293 次阅读

1)运用 Post Processing 导致帧率明显下降
​2)RectMask2D 是不是会频繁触发 SendWillRenderCanvases
3)Unity 3D Sence 为何一直处于已修改状态
4)Sprite Atlas 打 Bundle 的冗余问题
5)IL2CPP 在 Xcode 下增量编译问题

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

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

Rendering

Q:项目中运用了 Post Processing 后,帧率下降巨大。测试场景,模型面数 2w,普通的 Diffuse 材质 ,没有物理,没有特效。没开后处理时,低端机 30 帧。开启后处理,帧率抖动,最低达到 15 帧。后面只用到 Bloom 和 Color Grading。

A:如果 Bloom 用的不好,GPU 性能耗时高是较为正常的事情。Bloom 的上下采样次数、Filter 滤波的 Sample 点个数、屏幕的分辨率等都是影响 Bloom 性能的重要因素。

建议题主可以考虑阅读《Unity 引擎景深实现原理剖析与优化》这篇技术课程,里面优化 DOF 的方法依然可以用到 Bloom 上。

同时,也可以使用 GOT Online 中的 Overview 模式,直接查看项目在真机上(最好是高通芯片)的 GPU 耗时,看看 GPU 的具体超标情况:

该回答由 UWA 提供


UGUI

Q:RectMask2D 是不是会频繁触发 SendWillRenderCanvases?


A:是的,Rect Mask 2D 会持续每帧计算子节点的裁剪区域。所以 Rect Mask 2D 下面的元素如果比较多,耗时还是挺高的,这种情况可以换成 Mask 组件,虽然 Mask 的 Overdraw 会高一些。一个省 GPU,一个省 CPU,两个是需要权衡的。

感谢 Xuan@UWA 问答社区提供了回答


Editor

Q:Unity 3D Sence 一直处于已修改状态。刚切换过来也直接提示已修改。切换 Sence 并未作出任何修改,如下图:

虽然没什么难题,但切换别的场景或者退出的时候就要提示让保存了。
之前发现的一个原因是因为 UI 中存在套用的 Layout 组件呈警告状态。修改后 Sence 就恢复正常了。各位有遇到过这种问题吗?

A:所以说还是嵌套了 Layout 组件。这个会导致 Sence 一直处于修改状态。

感谢刘旭杰@UWA问答社区提供了回答


AssetBundle

Q:游戏中 UI 用 Sprite Atlas 做合图,打 Bundle 貌似碰到了一个冗余问题:(Unity 2019.4.1 lts 版本)。

Victory 目录有四张散图,以及一个 Sprite Atlas 文件做合图。Bundle 时把整个 Victory 为一个 Bundle。最终出来的 Bundle 结构如下:

也在网上搜了一些信息,尝试去掉 Sprite Atlas 的 Include in build 选项(效果未验证,纯粹验证 Bundle),Bundle 中少了一份冗余的 Texture 2D,但依旧有几个 Sprite 类型的散图。

疑问:
我理解是,Bundle 中已经有一个 sactx-1024x2048 的合图了,为什么还有 Sprite 类型的散图?这是否算冗余呢?
用去掉 Include in build 的方式,游戏中使用 UI Prefab 时,是否都需要用 Late Binding 才能使用图片(感觉很麻烦,UI 拼每个界面,都要程序写配套代码)?

A1:最开始描述的问题中(根据第一张截图)并未看到冗余的存在,也并非图集形式的打包结果。

回答如下:
对于图集本身的 Bundle 肯定是不算的,需要有各个散图的信息才能从整图中获取散图,不然就不知道你要的那个图在哪里。

不勾选 Include in build,Bundle 中就不会存在显式的图集依赖,必须使用延迟绑定传递信息(该图片从哪个图集中获取)给请求图片资源的对象。

感谢 Welkin_Totoro@UWA 问答社区提供了回答

A2:描述下我的思路:

勾选了 Include in build,Bundle 中就会有一份冗余:既包含合图,又包含散图。但这种情况下,程序不需要做特殊逻辑,界面就能表现正常(具体 Runtime 是否合图,未抓帧验证)。

不勾选 Include in build(正确做法):Bundle 就会只包含 Atlas,以及散图信息(不是完整的散图)。游戏内使用 Atlas Request Manager 来确保图片能正常显示,否则会错乱。如果自己实现了资源加载的话,可能还要自己找时机做 Atlas 资源卸载。

感谢 james@UWA 问答社区提供了回答


Build

Q:最近在研究加速打包问题,发现 IL2CPP 生成代码之后每次 Xcode 都是全量编译(直接 Build 而不是 Clean+Archive)。

我参考这里看了下,
https://forum.unity.com/threads/incremental-builds-for-il2cpp.365470/
对比了下如果 C# 代码没有变化,生成的 CPP 代码的内容确实不变。但是重新生成貌似会导致文件修改时间变化或别的属性变化,Xcode 依然是所有都编译了一遍。

A1:目前准备用群里大佬说的方法绕开:
“Freshair 17:01:28 打出的 Xcode 用 SVN 同步到 Xcode 打包项目下”

我用 Dnspy 看了下 IL2CPP.exe 直接修改代价有点大,而且不好维护。用 BeyondCompare 比较了下发现其实就 Preprocessor.h 和 Native 文件夹俩修改时间产生了变化。希望以后官方能注意这些细节。

感谢钱康来@UWA问答社区提供了回答

A2:介绍一篇文章《Unity Xcode 构建缓存》,里面写了一个程序解决 Unity 生成 Xcode 项目缓存问题。

WriteCache 使用 Rsync 增量传输,会节省时间,ReadCache 未做优化,实测用时 37 秒左右,1.5GiB 大小 Xcode 项目——UnityXcodeCache

感谢狂飙@UWA问答社区提供了回答

A3:我之前的做法是细化打包策略,资源打包细分为差不多 10 个步骤,对UI,特效,Lua(分三块,Core,模块,Luatable 配置),C# 层 Config,角色,场景,编译工程,资源覆盖,快速编译,生成 APK/IPA,云真机测试,组织成不同的打包命令提供给 CI。

如果是 C# 代码没变化,可以只做资源类的打包,对需要重新(此处可增量)打包的 AssetBundle,Lua,Config 等打包,打包后直接覆盖到 Xcode 工程,直接生成 IPA 包,跳过中间环节,构建过程可以细化到很细,如果你是 Lua 侧,那估计只需要打包 Lua 模块相关,1 分钟内就可以出到 IPA 包。

如果是 Xcode 代码也发生变化,这个可以结合 Ccache 进行提速,资源打包可以做分布式打包,多台黑苹果去打包各个模块的资源。再传递到版本机上整合,这个过程也可以 hook svn/git 的资源提交,在提交后做一次打包,再次发布的时候可以增量处理。

其实可以脱离 AssetBundle,把量产资源采用非 AssetBundle 的方式进行组织。避开不必要的导入导出及打包。

感谢 debugger@UWA 问答社区提供了回答

封面图来源于网络


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

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com

官方技术 QQ 群:793972859(原群已满员)

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册