2019.2版本UI耗時異常分析

1)2019.2版本UI耗時異常分析
2)如何保留stencil buffer的值
3)Unity使用HTTPS POST的問題
4)透明度混合Alpha值的算法問題
5)場景設置霧效異常html


Profiler

Q:我使用UWA GOT Online測試我本身打的Unity Android APK包,版本是Unity 2019.2.6f1 (64-bit),當我勾選多線程渲染和不勾選多線程渲染的狀況下,UWA網站分析的BuildBatch CPU均值不一樣。可是理論上勾選多線程渲染,BuildBatch CPU均值應該低,性能更好纔是,可是我勾選了多線程渲染,評測出來的BuildBatch CPU均值反而增高了,這是爲何呢?算法


開啓了多線程渲染json


未開啓多線程渲染多線程

A:咱們測試了空場景下一個文本每秒鐘更新的case,在小米5X上測試,發現確實會有很高的BuildBatch耗時。

經過查看Profiler的Timeline視圖發現,BuildBatch對應的是上一幀RenderThread的Gfx.PresentFrame,並不是UI自身耗時。
app

而在BuildBatch耗時低的其它幀,這裏等待的時間被統計在WaitForTargetFPS中。
編輯器

相對應的,在BuildBatch耗時高的這一幀,WaitForTargetFPS耗時只有0.01ms。
post

所以咱們認爲是Unity在這個版本中出現了Bug,致使的統計異常問題。
該回答由UWA提供性能


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問答社區提供了回答


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問答社區提供了回答,歡迎你們轉至社區交流:
https://answer.uwa4d.com/question/5e1336c01bf6ab772c8bb3a2

今天的分享就到這裏。固然,生有涯而知無涯。在漫漫的開發週期中,您看到的這些問題也許都只是冰山一角,咱們早已在UWA問答網站上準備了更多的技術話題等你一塊兒來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之「石」,也能攻你之「玉」。

官網:www.uwa4d.com
官方技術博客:blog.uwa4d.com
官方問答社區:answer.uwa4d.com
UWA學堂:edu.uwa4d.com 官方技術QQ羣:793972859(原羣已滿員)

相關文章
相關標籤/搜索