還原堆棧信息,分析地形系統使用ASTC格式的紋理導致Crash的問題

0x00 前言

在這篇文章中,我們選擇了過去一週Unity官方社區交流羣中比較有代表性的幾個問題,總結在這裏和大家進行分享。主要涵蓋了IL2CPP、Scripting、Virtual Reality、Graphics、Editor、Terrain、Plugins 、Education等領域,其中會着重介紹一下在原生的地形系統中使用ASTC格式紋理導致Crash的問題。

在文章結尾處我們還總結了社區小夥伴們過去一週在羣裏分享的一些乾貨連接。

同時,也歡迎大家加入我們這個討論乾貨的官方技術羣,交流看法分享經驗。
Unity官方社區交流羣:629212643

0x01 IL2CPP

Q: 有人遇到過GZipStream在安卓上沒辦法正常工作的問題麼?在Editor中工作是正常的。但是在安卓手機上會無法執行,查看logcat發現在執行時拋出了下面的異常:

Unable to find MonoPosixHelper
DllNotFoundException: MonoPosixHelper

屏幕快照 2018-07-13 上午11.47.11.png

A: 如果項目的scripting backend使用的是Mono,則在使用System.IO.Compression命名空間時的確會拋出類似上面的異常。但是如果使用IL2CPP的話,System.IO.Compression命名空間是可以正常使用的,包括GZipStream同樣也是可以正常使用的。
屏幕快照 2018-07-13 上午11.50.58.png

0x02 Scripting

Q: 如何求一個數最大能是2的多少次冪啊? 比如513最大是2的9次冪,就多了一位數. math裏有沒有這樣的方法,想要模擬cullingmask那樣的篩選層出來。

A: 用查找表,儘量限制在512之內。
10F001F907D2BA03480C0AA0C0DE624B.png

(鄭州(๑•̀.̫•́๑)大FC)

A:

int Exp(int i)
{
    int counter = 0;
    while(i > 1)
    {
        i = i >> 1;
        counter++;
    }
    return counter;
}

void outpuLayers(int layerValue)
{
    
    while(layerValue > 0)
    {
        int i = layerValue;
        int counter = 0;
        while (i > 0)
        {
            i = i >> 1;
            counter++;
        }
        Debug.Log(counter);
        i = 1;
        while (counter > 1)
        {
            counter--;
            i = i << 1;
        }
        layerValue = layerValue ^ I;
    }
}

(南京-科穆寧)

A: 查表法如果要支持20+的layer數,內存佔用爆炸。位運算log2正解,這裏下面也有個例子。
https://stackoverflow.com/questions/13654499/calculating-log-base-2
(上海-Weiqi “Xylt” Gu)

A: 範圍小用查表~ 範圍大用位移 ~ 不要用浮點運算~。(成都-xxp)

0x03 Virtual Reality

Q: 在開發Windows Mixed Reality時,編輯器會報錯“RenderTexture.GenerateMips failed: render texture does not have mip maps (set useMipMap to true).”這個是一個bug嗎?Unity版本爲Unity2017.1.1f1, Unity2017.1.2f1, Unity2017.21f1。
A13A5C9EB89FDAD98828621D7CB75673.png

A: 這的確是一個bug。細節可以查看:https://forum.unity.com/threads/beta-7-case-943170-windows-mixed-reality-far-clip-and-rendertexture-generatemips-error.488714/

這個bug已經修復了。但是當時還沒有backport到2017.1和2017.2,也就是你用來測試的版本。
推薦你使用2017.4來測試和進行開發。2017.4版本作爲一個長期維護版本,會持續修復已經知道的bug。

0x04 Graphics

Q: tonemapping和打包設置裏colorspace是衝突的嗎?是不是用tonemapping,colorspace需要改成線性?

A: 用tonemapping的話要用hdr,hdr最好和線性空間一起用,才能保證準確度。如果你的項目設置爲gamma的話,postprocessing中的color grading會有一個警告的。
屏幕快照 2018-07-13 下午2.32.53.png

Q: 難道我理解錯了。攝像機可以開HDR,但是打包到手機渲染設置裏默認是不開的啊 我可不可以 用HDR算出來的結果 通過mapping 轉換成ldr給手機顯示
A: tonemapping的作用也是爲了將一個高動態範圍的顏色數據映射回可用顏色空間,爲的是不被顯示屏幕截斷色彩。(北京-哎呀)
A: 因爲顯示器很少支持hdr,安卓手機更是565顏色居多。tonemap就是一個簡單s曲線remapping。(深圳-topameng)

Q: 攝像機開啓HDR並不表示移動端開啓HDR吧。
A: 手機上不是固定fp16的,可以自己調,如果設置沒有hdr backbuffer, 你攝像機上的標記一點用也沒有。(深圳-topameng)

小貼士

這裏可以和大家科普一下Graphic Setting中的各個tier和設備的對應關係:Graphics Settings內的Tier設置,在運行時會根據GPU來選擇對應的Tier。應用相關的設置。具體各個Tier和設備的對應關係如下:

Tier 1:
Android - all devices that have support for OpenGL ES 2 only
iOS - all devices before iPhone 5S (not including 5S, but including 5C), iPods up to and including 5th generation, iPads up to 4th generation, iPad mini first generation
Desktops: DirectX 9, HoloLens

Tier 2:
Android - all devices with OpenGL ES 3 support,Vulkan
iOS - all devices starting from iPhone 5S, iPad Air, iPad mini 2nd generation, iPod 6th generation
AppleTV

Tier 3:
Desktops: OpenGL, Metal, DirectX 11+,Vulkan

具體也可以查閱相關文檔。

Q: unity自帶的屏幕射線反射效果一般,然後我找了好久,找到一個livenda lab開發的,居然離屏追蹤,就是現在還沒出成品。有好的推薦嗎?
A: 可以參考羣裏@上海-CGBull在他的文章中的實現。
Unity_StochasticScreenSpaceReflection-實現篇:
https://zhuanlan.zhihu.com/p/38303394
(北京-小小光)

Q: 我這裏想要擾動的方向是隨機的怎麼弄啊 在腳本里setfloat感覺是硬切的。
32A41337C2F9B902D9B43EC5D821C34D.png

A: 從一張噪聲貼圖裏讀。
15FBFCCBF78868125F605311A25090A9.png
可以看看和失真效果相關的這篇博客:
https://zhuanlan.zhihu.com/p/37696836。(北京-破曉)

Q: 我想要的就是一團紋理在球上面隨機方向位移,並且隨時間變化。
A: 可以參考這篇文章:https://blog.csdn.net/panda1234lee/article/details/52085375
總之採樣的時候以_Time作爲種子取個噪聲就行。(北京-破曉)

Q: 有人實現過手機上面能用的雪地踩踏效果嗎?主美還想着要那種曲面細分的效果。。。戰神 古墓麗影。。。
A: 思路並不複雜。簡單的說, 就是Mesh變形。
1372105-c552ebae7261538b.gif
至於古墓麗影的那個案例,之前@逍遙劍客 也在知乎上分享過。http://tombraider.tumblr.com/post/131825841425/dev-blog-snow-tech-and-houdini-simulations-mike

A: https://www.cnblogs.com/murongxiaopifu/p/7887614.html (北京-suzakul)

0x05 Editor

Q: 求教animationclip的inspector上顯示的該資源的內存佔用大小數據是如何獲得的?屏幕快照 2018-07-14 下午8.50.47.png

A: 你可以調用AnimationUtility.GetAnimationClipStats(clip)來獲取某個clip的status,即AnimationClipStats類的實例,其中的size字段即inspector上顯示的內存佔用大小。可以參考下面的代碼:

        Assembly asm = Assembly.GetAssembly(typeof(Editor));
        getAnimationClipStats = typeof(AnimationUtility).GetMethod("GetAnimationClipStats", BindingFlags.Static | BindingFlags.NonPublic);
        Type aniclipstats = asm.GetType("UnityEditor.AnimationClipStats");
        sizeInfo = aniclipstats.GetField("size", BindingFlags.Public | BindingFlags.Instance);

另外,c#部分的代碼其實有開源的。你也可以參考github上的代碼:https://github.com/Unity-Technologies/UnityCsReference/blob/3cfc6c4729d5cacedf67a38df5de1bfffb5994a3/Editor/Mono/Inspector/AnimationClipEditor.cs

0x06 Terrain

Q: 有人遇到過地形上用的紋理的紋理格式設置爲astc,在手機上會崩潰的問題嗎?我的unity版本是2018.1。

A: 遇到過這個問題。我下午也做了一些測試,這其實並非Unity2018上出現的新bug。我測試了一些2018之前的版本,比如2017.3.0p1,發現同樣會由於在原生地形系統中使用astc格式紋理而出現crash。
屏幕快照 2018-07-15 下午12.20.33.png

屏幕快照 2018-07-15 下午12.20.43.png

不過這個問題我已經提交了Bug報告給開發,開發那邊已經知道了。以後的版本會修掉。並且目前在原生地形中使用ETC2格式的紋理是沒有問題的。
不過,我們其實可以通過crash日誌信息,來看看程序是在哪一步crash掉的。同時,也可以在這裏和大家分享一下如何通過crash日誌來還原堆棧信息。
首先說明的是,我這裏使用的Unity版本是2018.1.0f1,並且使用的Script Backend是Mono。
打開手機上的測試程序,查看程序crash時的日誌:
屏幕快照 2018-07-14 下午9.47.46.png
在這份堆棧信息裏,我們可以看到例如0049b647這樣的數字,它們是在crash時,程序正在執行的方法的內存地址。每行的結尾則是所使用的庫,這裏是libunity.so
但是,內存地址對我們來說顯然沒有什麼意義,所以接下來我們需要將內存地址轉換成我們可以看懂的內容。
在Unity 5.3.6之後的版本,我們都提供了libunity的符號表。
屏幕快照 2018-07-14 下午10.31.58.png
在Mac上,符號表的路徑是:

/Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Symbols

在windows上,符號表的路徑是:

C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Symbols\armeabi-v7a\libunity.sym.so

需要注意的是,接下來我們使用的符號表版本一定要和你打包所使用的Editor版本一致。
有了符號表,接下來我們還需要NDK的addr2line工具。你可以在你的NDK目錄下找到它:

toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line

OK,萬事俱備,我們接下來就來解析一下第一條內存地址所對應的方法。

./arm-linux-androideabi-addr2line -f -C -e libunity.sym.so 0049b647

可以看到crash的方法是:屏幕快照 2018-07-14 下午10.48.44.png

construct_block_size_descriptor_2d似乎還不太明顯。我們再往回追。
屏幕快照 2018-07-14 下午10.50.40.png
原來是在做DecompressASTC相關的操作時crash了。

當然,這個bug已經提交了,並且會在以後的版本中修復的。現在大家可以在地形中使用ETC2格式的貼圖

0x07 Plugins

Q: 有沒有大佬 知不知道 unity支不支持 64位動態庫的調用?使用安卓平臺。
A: 在Unity2018.1.0 Beta 2版本中提供了對 Android 64-bit ARM(experimental)的支持。
首先要將scripting backend設置爲IL2CPP,之後就可以在Player Setting中選擇ARM 64了。屏幕快照 2018-07-14 下午11.11.39.png

另外,在剛推出的2018.2正式版中,對ARM64的支持應該已經很完善了。

0x08 Education

Q: 請問目前Unity提供的資質認證中,是隻有“專家程序員認證”有培訓課程嗎?B22A35F67942884B811DFAEF30D03EF1.png

A: 除了初級開發者考試有相應的課程外,其他證書的課程還在製作中,暫時還沒有。初級的8月份纔會搬到coursera,中文的現在網易雲 51cto 已經有了。http://study.163.com/course/introduction/1005268010.htm

0x09 後記

這一週恰好也迎來了Unity2018.2的正式版本的發佈,大家可以通過Unity Hub來直接下載:
屏幕快照 2018-07-15 下午12.42.00.png
也可以點擊這個鏈接來下載:https://unity3d.com/cn/get-unity/update

好了,以上就是想和大家分享的幾個在羣裏討論的小問題。
再次,歡迎大家加入我們這個討論乾貨的官方技術羣,交流分享呀。
Unity官方社區交流羣:629212643

Ref

這裏是社區小夥伴們過去一週在羣裏分享的一些乾貨連接:
[1]Don’t Re-invent Finite State Machines: How to Repurpose Unity’s Animator:
https://medium.com/the-unity-developers-handbook/dont-re-invent-finite-state-machines-how-to-repurpose-unity-s-animator-7c6c421e5785
[2]Calculating Log base 2:
https://stackoverflow.com/questions/13654499/calculating-log-base-2
[3]【翻譯】Shader · 冰:
https://zhuanlan.zhihu.com/p/37696836
[4]Shader特效——實現“噪聲”【基於ShaderToy】【GLSL】:
https://blog.csdn.net/panda1234lee/article/details/52085375
[5]小隨筆:利用Shader給斯坦福兔子長毛和實現雪地效果:
https://www.cnblogs.com/murongxiaopifu/p/7887614.html
[6]Dev Blog: Snow Tech and Houdini Simulations:
http://tombraider.tumblr.com/post/131825841425/dev-blog-snow-tech-and-houdini-simulations-mike

Unity官方社區交流羣:629212643

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章