还原堆栈信息,分析地形系统使用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

posted @ 2018-07-17 13:52  慕容小匹夫  阅读(2215)  评论(0编辑  收藏  举报