1)2019.2 版本 UI 耗时异常分析
2)如何保留 stencil buffer 的值
3)Unity 使用 HTTPS POST 的问题
4)透明度混合 Alpha 值的算法问题
5)场景设置雾效异常


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 提供


Rendering

Q:请问 Unity 中 Camera 的 OnRenderImage 调用前是不是把 stencil buffer 的值清掉了?

A:对,Stencil buffer 是 Depth buffer 后 8 位,opacity 画完了就清了。如果你不想清空,有几个办法:

感谢张言丰@UWA问答社区提供了回答


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问答社区提供了回答


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问答社区提供了回答


Rendering

Q:场景设置雾效开启状态,通过 AssetBundle 包加载的资源没有雾的效果。Graphics 里的 fog 的配置也试过了,没效果;在 PC 上是正常的,手机上没效果。

A:Graphics 里的 fog 的配置只能保证变体不会被这里剔除,并不能保证你打 AssetBundle 的时候变体一定不丢失。修改了 Graphics 之后,一定要删除所有 AssetBundle,重新打包才能生效,增量打包 AssetBundle 无效。其次,最好使用 ShaderVariants,保证打包 Shader 的时候,变体一定存在(勾选相关 fog 宏定义)。

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


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


↙↙↙阅读原文可查看相关链接,并与作者交流