【厚積薄發】本地資源檢測,特效檢測中Overdraw相關問題


這是第230篇UWA技術知識分享的推送。今天我們繼續為大家精選了若干和開發、優化相關的問題,建議閱讀時間10分鐘,認真讀完必有收獲,

UWA 問答社區:answer.uwa4d.com

UWA QQ群2:793972859(原群已滿員)

本期目錄:

  • 本地資源檢測,特效檢測中Overdraw相關問題
  • Android上如何加速判定Bundle文件是否存在
  • xLua pcall異常捕獲
  • Mipmap和帶寬

  • Timeline卡頓嚴重時,Clip被完全跳過沒有執行

Rendering

Q:咱們這個特效資源檢測Overdraw和實際檢測差距有點大,是不是統計峰值比較好一些?有可能一個特效播放時間特別長,但是峰值就很短的時間,這樣一平均Overdraw就很低了。



A:首先要談談Overdraw的定義問題:

1. Overdraw是一個描述像素重復繪制次數的概念。單個像素的重復繪制次數很容易理解,但是對于一個特效的Overdraw,筆者還沒有找到什么公認的“標準”的計算公式,也不存在什么“官方”的定義,

對于一幀來說,Overdraw值可以定義為該幀總體繪制像素的次數 / 屏幕上實際繪制的像素數,而這個值也不能簡單理解為“繪制的層數”。(試想如果總共在屏幕上繪制了1000個像素,其中只有一個像素繪制了10層,那這個重復繪制的像素對Overdraw值得貢獻也是可以忽略的,計算結果為:1009/1000=1.009)。而對于整個特效播放過程中的Overdraw,具體公式如何定義,又是一個問題。

2. sunbrando的開源庫(https:http://github.com/sunbrando/ParticleEffectProfiler)的計算方法:整個播放過程中,

分子是對每一幀繪制像素的次數求和,分母是對每一幀屏幕上實際顯示的像素數求和

這個公式確實可以從整體上衡量一個特效播放過程中的Overdraw。但是這種計算存在這樣一個問題:有些幀特效占屏幕的比例很大,有些幀特效占屏幕的比例很小,而運算結果受屏幕占比大的幀影響比較大,比如第一幀繪制了1000個像素,只繪制了1層,而第二幀繪制了2個像素,繪制了10層,那么計算出的值為:(1000×1 + 2×10) / (1000 + 2) = 1.018 ,

對特效Overdraw的計算與上述開源庫計算公式是相同的,不同的是特效播放的邏輯與相機對準的方式,

影響兩個工具計算結果不同的因素有:

1. 相機的對準方式不同。UWA的工具有一套相機自動對準的邏輯,相機的擺放不同,會造成Overdraw不同。

2. 播放的時機不同。UWA的工具會創建好場景后,自動加載并實例化特效,進行播放。而開源庫ParticleEffectProfiler的方案是先把特效放到場景中,啟動場景后再執行相關的邏輯,進行檢測,

樓主的案例中,除了相機對準方式不同導致兩個工具計算結果不同之外,很大程度上受到了獲取的特效播放時機的影響。

使用開源庫工具進行檢測,發現抓取相機的Overdraw數據前,已經進行了三次Update,如下圖所示,也就是說,特效的Overdraw是從第4幀開始統計的。這與該工具的代碼邏輯有關,就不對原因進行分析了。


而前三幀恰恰又是在數值上貢獻最大的幀,如下圖所示,前三幀特效中有一個面片占了很大的屏幕空間,


而第四幀開始,特效的像素占比就小了很多,


這是兩個工具即使使用相同的對準方式,Overdraw計算結果也不相同的原因。

另外,UWA的特效檢測還存在一個問題:相機視錐體的Size是不斷調整的,那么不同的幀特效的屏幕占比會因此而改變,像素的繪制量也不同,對上述Overdraw值計算公式的貢獻也就不一樣。也就是說,相機的Size越小的幀,特效屏幕占比越大,對結果的影響越大。

這里有兩套解決方案:

1. 換公式,每幀都計算出OverdrawRate,再求平均。

2. 用戶自定義相機,相機的視錐體保持固定,這樣就是放棄自動對準,使相機的設置更接近用戶的實際使用環境,

UWA的工具會不斷迭代,根據需求盡可能找到一套最佳策略來幫助開發者對項目進行規范。

如果在優化中要使用工具進行檢測,并衡量優化的結果,建議使用一套工具即可。使用同一套標準至少可以對資源的性能進行一個排名,據此來選擇優化的優先級,并使用同一套標準評估優化結果,

感謝Prin@UWA問答社區提供了回答,迎大家轉至社區交流:

https:http://answer.uwa4d.com/question/5fc7171310a17c6c2b09d47b

AssetBundle

Q:我們在Android平臺上打包時,把Bundle放到Streaming Assets中,Patch文件放到持久化目錄中,在啟動時判斷:Patch目錄有Bundle就用Patch目錄的,沒有就看Streaming Assets目錄有沒有,

問題是:Android判斷Streaming Assets下是否有文件,要用www或UnityWebRequest,這兩種都是異步讀文件,等待異步操作結束需要幾毫秒以上,導致判斷邏輯耗時很長(Bundle 較多)。

想請教下大家是怎么處理 Android上的文件判定問題呢?

A1:Streaming里放個資源字典文件,用這個判斷,

感謝lanyt@UWA問答社區提供了回答

A2:可以這樣來處理:

有一個全局的Bundle資源的配置文件,里面記錄了所有Bundle的資訊,這里面會包含其相對路徑。只有從包里面讀這個文件是需要異步的,如果從Patch目錄讀這個文件也是同步的(例如使用FileStream)。

得到了所有Bundle的相對路徑后,在實際需要加載某Bundle時,先使用File.Exist或者直接判斷AssetBundle.LoadFromFile的返回值是否為null來判斷Patch目錄是否有該Bundle,如果沒有的話再使用包內路徑重新調用AssetBundle.LoadFromFile即可,

經測有效,把文件判斷分散開,Patch目錄可以直接用File,不存在就認為是在Streaming

Assets目錄,最后利用Load的結果來更新,看是否存在的記錄。

感謝范君@UWA問答社區提供了回答

A3:有一個不錯的開源庫,能夠同步讀取StreamingAssets下的文件:

《BetterStreamingAssets》

https:http://github.com/gwiazdorrr/BetterStreamingAssets

感謝張迪@UWA問答社區提供了回答,迎大家轉至社區交流:

https:http://answer.uwa4d.com/question/5fc9ad5a10a17c6c2b09d4f9

LUA

Q:想請問下在xLua中使用pcall/xpcall實現C#中的Try Catch功能的時候,在iOS/Android/模擬器等平臺上,有什么需要注意的地方。

由于對Lua底層不是很了解,想確認下,線上項目使用是否可行。還有這個的性能消耗有多少,Update里可以用嗎?

項目使用的是xLua,版本是2.1.14,Unity版本是2019.4,

A:大范圍的使用中,pcall和xpcall本身肯定有一定的性能影響,不過我們倒是沒有做過很完備的性能測試對比,印象中之前做過一些檢索,沒有找到特別明確的答案,

Lua中源碼的實現對比可以參考這里:

https:http://stackoverflow.com/questions/16642073/whats-the-difference-behind-normal-function-call-and-pcall/16642612

可以看到pcall的確比常規的call多做了一些事情,只是這是Lua做異常捕獲的唯一方式,當你不想游戲邏輯被錯誤資訊打斷的時候,只能使用它。

pcall/xpcall在各種平臺和模擬器上除了略微的性能影響之外沒有任何問題,因為它是Lua原生的方式,如果使用LuaJIT,注意一下Lua和LuaJIT下的區別封裝即可。

感謝賈偉昊@UWA問答社區提供了回答,迎大家轉至社區交流:

https:http://answer.uwa4d.com/question/5fc4bcbd10a17c6c2b09d3ca

Rendering

Q1:請問,Mipmap究竟能不能降低帶寬,如果不能降低,能否詳細告訴一下原因,謝謝。

A1:可以降低!

Mipmap是為了解決Texel和Pixel沒有1:1對應的一種處理方式。一般來說如果處理遠處物體的渲染,依然使用正常的紋理采樣,那么其實1個Pixel就一般需要采樣到多個不相鄰的Texel[1:n的關系],那么不相鄰這就可能涉及到一個Cache Miss的問題,而Cache Miss必然需要從顯存中重新采樣紋理數據,這自然就會消耗帶寬。


感謝會丟鍋的Coder@UWA問答社區提供了回答

A2:是可以降低帶寬開銷的,

主要是由于在渲染相鄰Pixel的時候,采樣的Texel可能是在內存中不連續的,而GPU的Texture Cache是很小的,

如果沒有Mipmap,在渲染遠處物體時,GPU可能需要不停的在儲存Texture的各段Memory不停的訪問,Cache Miss很嚴重。而使用了Mipmap后,相當于離線將每個Texel覆蓋的Texture的面積變大,這樣可以提升Texture Cache的命中率,從而減少直接從內存讀取數據的次數,從而節省了帶寬的開銷。

感謝范君@UWA問答社區提供了回答

Q2:請問上文中:

1. “而使用了Mipmap后,相當于離線將每個Texel覆蓋的Texture的面積變大”,這里是Pixel還是Texel?

2.還有就是Memeory是指內存是吧?不是已經把一張圖提交給了GPU顯存了嗎?


A:可以看下我知乎的這個回答,解決你對Pixel和Texel的疑惑:

《shader 中,fwidth 或者說 ddx/ddy 到底是什么意思?》

https:http://www.zhihu.com/question/329521044/answer/1286662690

感謝止戈@UWA問答社區提供了回答,迎大家轉至社區交流:

https:http://answer.uwa4d.com/question/5fc61e1410a17c6c2b09d433

Timeline

Q:Timeline,如果在播放時卡頓嚴重,會出現前面位置的Clip被完全跳過沒有執行,有沒有人碰到過類似的問題?


Timeline 信號的這個描述,是不是即使信號跳過了,依舊會執行?

The Retroactive property, when enabled, will trigger the signal if the timeline begins playing after the signal’s time.

The Emit Once property, when enabled, will trigger the signal only once when the timeline loops.


A:勾上之后是會執行,具體邏輯可參考TimeNotificationBehaviour腳本(Timeline中Signal Track的mixer邏輯腳本),如下做了簡單注釋:



如果需要倒放也會Trigger,也可以參考這個擴展自己的Timeline。

https:http://answer.uwa4d.com/question/5fc5ff6310a17c6c2b09d42d

封面圖來源:Barracuda Style Transfer code sample

https:http://lab.uwa4d.com/lab/5fc043430f247485d92bacaa

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

官網:www.uwa4d.com

官方技術部落格:blog.uwa4d.com

官方問答社區:answer.uwa4d.com

UWA學堂:edu.uwa4d.com

0 条回复 A文章作者 M管理員
    暫無討論,說說你的看法吧