技术分享连载(九十八)
- 作者:admin
- /
- 时间:2018年02月06日
- /
- 浏览:3923 次
- /
- 分类:厚积薄发
本期聚集了这些话题:半透明渲染对性能的影响、PSS内存在部分机型上暴涨、Action函数的性能、ShaderVariantCollection生成设定......
我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。
UWA QQ群:793972859
UWA 问答社区:answer.uwa4d.com
渲染
Q1:在UWA性能优化报告中,有个专门针对半透明渲染的性能消耗说明,导致半透明渲染高开销的一般有UI、场景和粒子等,那么想知道,UI(好像大部分UI都是有带半透明的)对半透明的影响有多大?在制作UI上有没有什么注意事项?
就现在的大多数移动项目而言,这个影响是很大的。在半透明渲染的CPU端,主要有两点需要注意:
(1)UI Draw Call;(2)UI的重建。
UI Draw Call越高,其渲染耗时越大,所以,建议在题主在UWA测评报告中的CPU详细性能堆栈中,查看UI的Draw Call使用情况。一般移动游戏,都建议将其峰值控制在40以下。而如果降低UI Draw Call,主要还是图集打成Atlas、避免穿插等等,具体的可自行Google。
UI重建同样会造成开销过大,主要表现在主线程的self等待开销中,当UI重建的网格体量较大时,这种情况容易出现。所以,尽可能避免不必要的UI网格重建,也是研发团队在UI制作时需要特别注意的地方。
该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a731c34e3b569146eeaeb35
内存
Q2:最近我们发现游戏在魅族Pro5在运行时,PSS内存会暴涨,使用UWA GOT测试,发现资源内存并都没涨,而且这个问题目前只在魅族Pro5上出现,其它机型没有这个问题,请问该怎么解决呢?
我找了一个简单工程,如下图NPC名字跟阴影不能同时显示,否则就会导致PSS内存暴涨。
如下图,GfxDriver内存一直在涨,一秒涨2MB左右,只增不减。运行久了,魅族Pro5会崩溃。
如果GfxDriver和PSS一起升高,那么说明GPU方面存在Bug的概率很高。只能建议如下:
(1)尝试在特定机器上不加入“UI阴影”,从制作上进行规避;
(2)尝试在更高Unity版本中运行Demo,查看其内存问题是否会修复。
后经题主再次反馈,把 Unity版本从5.4.5升级到5.5.6,然后把 auto graphics api勾选上后,内存爆涨的问题就解决了。如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a741b6fe3b569146eeaeb3a
其他
Q3:new Action(Function)和直接传入Function函数区别是什么?例如以下两个函数有啥区别?
void Method(Action action)
{
}
void MethodCallBack()
{
}
void Start()
{
//Method(new Action(MethodCallBack)) 和 Method(MethodCallBack) 有啥区别? 哪个性能高?
}
两者理论上是一样的,因为Method(MethodCallBack)在编译时,编译器会自行给它包一层new Action。所以这两种写法从编译结果来看,是一致的。
这两种写法如果在项目中只是偶尔调用,是没有问题的,但如果被频繁调用,那么比较好的写法是在外部定义一个Action,然后将该Action传给Method来进行复用,即
Action act = New Action(MethodCallBack);
void Start()
{
Method(act);
}
该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a72f4dba69c4f5b6d1a9949
动画
Q4:我们使用的是老动画系统,动画是单独打包的,在运行时通过AddClip添加动画到模型上去,但是AddClip会触发RebuildInternalState导致波峰,那么大家是怎么解决这个RebuildInternalState触发的波峰呢,难道是只有老动画系统才会发生这个情况吗?
RebuildInteralState在Mecanim中也是有的,只是不叫这个名字了,而是变成了“Animator.Initialize”,两者的作用和触发时刻都差不多。
AddClip确实很耗时,这个在以前就是如此,所以建议如无特殊需求,AddClip尽可能在切场景时进行替换,在Runtime(特别是战斗中时)是不建议频繁调用AddClip的。
该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a702a5d1c1b88125112c7b8
资源管理
Q5:我查看了UWA上所有关于ShaderVariantCollection的资料之后,自己动手开始做一个ShaderVariantCollection预加载Shader,由于Shader变种比较多以及方便维护,准备写一个工具查找所有需要的Shader.keywards组合, 在生成ShaderVariant的时候有一个参数是PassType。通过Material.GetTag(“LightMode”, true)查找的时候有两个问题:
1)一个Shader里面可能有多个SubShader或者Pass使用不同的LightMode,但是通过GetTag(“LightMode”, true)只能找到第一个;
2)有一些Shader里没有设置Tags{“LightMode”=XXX}(主要是第三方插件),这个怎么处理比较合适?
我查找工具脚本在这里:https://paste.ubuntu.com/26462717
题主可以尝试反射大法,可以同时找到Keyword和Passtype。
static MethodInfo GetShaderVariantEntries = null;
public static List<string> GetShaderKeywords(this Shader target)
{
if (GetShaderVariantEntries == null)
GetShaderVariantEntries = typeof(ShaderUtil).GetMethod(“GetShaderVariantEntries”, BindingFlags.NonPublic | BindingFlags.Static);
int[] types = null;
string[] keywords = null;
object[] args = new object[] { target, new ShaderVariantCollection(), types, keywords };
GetShaderVariantEntries.Invoke(null, args);
keywords = args[3] as string[];
List<string> result = new List<string>();
foreach (string keyword in keywords)
{
foreach (string t in keyword.Split(' '))
{
if (!result.Contains(t))
result.Add(t);
}
}
return result;
}
感谢钱康来提供了以上回答。
该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a6ace59cd437d6b816b7ef8
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站(answer.uwa4d.com)上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(仅限技术交流)