2019.2版本UI耗时异常分析
- 作者:admin
- /
- 时间:2020年01月14日
- /
- 浏览:2619 次
- /
- 分类:厚积薄发
1)2019.2版本UI耗时异常分析
2)如何保留stencil buffer的值
3)Unity使用HTTPS POST的问题
4)透明度混合Alpha值的算法问题
5)场景设置雾效异常
这是第190篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。
UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)
Profiler
Q:我使用UWA GOT Online测试我自己打的Unity Android APK包,版本是Unity 2019.2.6f1 (64-bit),当我勾选多线程渲染和不勾选多线程渲染的情况下,UWA网站分析的BuildBatch CPU均值不同。但是理论上勾选多线程渲染,BuildBatch CPU均值应该低,性能更好才是,但是我勾选了多线程渲染,评测出来的BuildBatch CPU均值反而增高了,这是为什么呢?
开启了多线程渲染
未开启多线程渲染
A:我们测试了空场景下一个文本每秒钟更新的case,在小米5X上测试,发现确实会有很高的BuildBatch耗时。
通过查看Profiler的Timeline视图发现,BuildBatch对应的是上一帧RenderThread的Gfx.PresentFrame,并非UI自身耗时。
而在BuildBatch耗时低的其它帧,这里等待的时间被统计在WaitForTargetFPS中。
相对应的,在BuildBatch耗时高的这一帧,WaitForTargetFPS耗时只有0.01ms。
因此我们认为是Unity在这个版本中出现了Bug,导致的统计异常问题。
该回答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5e0ef38473f93355f9668073
Rendering
Q:请问Unity中Camera的OnRenderImage调用前是不是把stencil buffer的值清掉了?
A:对,Stencil buffer是Depth buffer后8位,opacity画完了就清了。如果你不想清空,有几个办法:
- OnRenderImage逻辑放到Onpostrender里
- OnRenderImage逻辑放到Command buffer里
- 用Command buffer把Depth buffer的内容提前Copy一份暂存(这个套路画Volumetric fog,毛发之类的经常用)
感谢张言丰@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5e153e7afd2e373ffa7eaae5
Network
Q:大家有没有2018以前版本的HTTPS POST的解决方案?
现在测试的情况是,使用UnityWebRequest在编辑器上可以过,但是会被降级为HTTP,高版本Android会被ClearText阻止,并且有部分机型在Android添加ClearText权限也无法绕开。
使用C#原生的HttpWebRequest API,Post会收到400错误。确认流里面参数无误,使用UnityWebRequest读参数,然后直接把Uploader里面的bytes复制给HttpWebRequest的上传流,也会收到400。
测试过使用.NET 2.0,没有效果。不知道大家如何解决高版本Android的HTTPS问题?
A:亲测可用:
public static string Post(string url, string obj, int timeoutSeconds = 15)
{
if (string.IsNullOrWhiteSpace(url))
return "";
Encoding encode = Encoding.UTF8;
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
myRequest.ContentType = "application/json;charset=utf-8";
myRequest.Method = "POST";// HttpUtil.UrlMethod.POST.ToString();
if (timeoutSeconds < 3)
timeoutSeconds = 3;
byte[] bs = null;
myRequest.Timeout = timeoutSeconds * 1000;
if (obj != null)
{
bs = Encoding.UTF8.GetBytes(obj);
myRequest.ContentLength = bs.Length;
}
else
myRequest.ContentLength = 0;
using (Stream reqStream = myRequest.GetRequestStream())
{
if (obj != null)
reqStream.Write(bs, 0, bs.Length);
reqStream.Close();
}
try
{
using (HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(),encode))
{
var responseData = reader.ReadToEnd().ToString();
return responseData;
}
}
}
catch (WebException ex)
{
throw ex;
}
}
感谢郑骁@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5e0ec006ce53cf56002cae9c
Rendering
Q:我比较关心Alpha值的算法。
假如有两个颜色,S=1,0,0,0.5,D=0,0,0,1。按照PS里的透明度算法Oa=1-(1-Sa)(1-Da)来算,最终颜色O的Alpha值为1-(1-0.5)(1-1)=1,如图1。
按照Shader中的Alpha blended的算法,Oa=Sa*Sa+Da(1-Sa),最终颜色O的Alpha值为0.25+0.5=0.75,不知道是不是我自己哪里算错了。
总之,经过实际测试,PS和Unity里模拟出的效果是一致的,如图2。也就是说按照Alpha blended混合方式混合出来的Alpha值也应该是1才对。
Unity中的Shader以及颜色设置没有任何问题,两个颜色的绘制顺序也是正确的,如果有问题,是不会跟PS里的效果一样的。只是我自己计算的时候,不知道哪里出了问题。
图1
图2
A1:一般颜色混合只针对RGB,Alpha并不参与混合公式的计算。也就是说对于Alpha,你Shader输出是多少就是多少。ScreenBuffer的Alpha并不会因为把它设置为0.5,就变成半透明,所以有很多效果可以hack这个Alpha通道来传递数据。
感谢fubbi1000@UWA问答社区提供了回答
A2:Shader中的Alpha的输出是可以自己定义的,你可以看看Blend那一行是不是有逗号,逗号后就是Alpha通道的计算方式:
Blend SrcAlpha OneMinusSrcAlpha, One One
感谢王宇@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5e11017b73f93355f966808d
Rendering
Q:场景设置雾效开启状态,通过AssetBundle包加载的资源没有雾的效果。Graphics里的fog的配置也试过了,没效果;在PC上是正常的,手机上没效果。
A:Graphics里的fog的配置只能保证变体不会被这里剔除,并不能保证你打AssetBundle的时候变体一定不丢失。修改了Graphics之后,一定要删除所有AssetBundle,重新打包才能生效,增量打包AssetBundle无效。其次,最好使用ShaderVariants,保证打包Shader的时候,变体一定存在(勾选相关fog宏定义)。
感谢郑骁@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5e1336c01bf6ab772c8bb3a2
封面图来源于网络
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859(原群已满员)