技术分享连载(八十六)
- 作者:admin
- /
- 时间:2017年11月14日
- /
- 浏览:3273 次
- /
- 分类:厚积薄发
本期聚集了这些话题:导航网格信息导出、LoadLevelAsync加载效率、使用IL2CPP后的Mono内存理解...
UWA一下,你就知道~
我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。
UWA QQ群:793972859
UWA 问答社区:answer.uwa4d.com
加载
Q1:在手机上测试LoadLevelAsync和LoadLevel的加载速度,同一个场景,LoadLevelAsync要比LoadLevel多花费40%左右的时间,请问这是正常的么?LoadLevel会有卡顿,导致Loading进度条不平滑,但是LoadLevelAsync好像又会增加Loading的时间?
我项目中场景动态加载的做法是,是把物件做成Prefab,然后根据主角的位置做动态加载相应的Prefab,用的是Resources.LoadAsync方法。现在加载一些比较大的物件时,在红米2等低端机上,仍然比较卡,要消耗200ms以上。请问有什么好的方式,能平滑这个加载过程么,谢谢!
LoadLevelAsync一般情况下是要比LoadLevel慢的,但是否要慢40%,这个其实是根据每个场景所要加载的不同量而定的,并不是确数。 LoadLevel和LoadLevelAsync其实最本质的区别,是前者一定要在下一帧结束前完成加载操作,所以当加载场景较大时,其随后的单帧开销就会很大,而后者则没有这个限制,引擎可以根据当前的使用情况或者ThreadPriority(这个值是是否对LoadLevelAsync有影响,还没做过具体实验,但对于LoadAsync确实有影响 )来自行调控。 但还需要说明一点的是,不是说使用Async,它就一定是绝对平滑,下图红框是LoadLevel,绿框是LoadLevelAsync操作。
关于真正“平滑”异步的加载方式,Unity引擎目前还是没有的。在遇到较为复杂的Prefab(比如大纹理、多AnimationClip等等)时,其加载依然会出现卡顿。如果想要缓解该问题,建议如下:
(1)先定位具体是哪个Prefab加载造成的CPU耗时较高;
(2)查看该Prefab中是否含有大量加载耗时开销(比如大纹理、较多AnimationClip、较多Shader等等);
(3)定位后尝试将其进行前期预加载,从而缓解该Prefab加载时的局部高开销。
该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a06cc3cc4ccc1804bea31ac
内存
Q2:我使用了IL2CPP后是否还存在Mono内存呢?使用IL2CPP后,通过Profiler工具获取的managedObject(例如: int32[])是哪种内存?
可以简单地认为,Il2CPP只是替换掉了Mono的虚拟机实现,所以该分配堆内存的地方还是会一样的分配(可能会有某些细节的地方不一样)。
IL2CPP在堆内存分配方面和Mono 最大的不同主要是Reserved Total 是可以下降的,而 Mono的 Reserved Total 只会上升不会下降。
该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a0271297acd3ac1606d5d32
渲染
Q3:场景自动烘焙的导航网格信息保存在 NavMesh.asset 中,打开可以可以看到数据如下:
项目需要在服务器上进行寻路,希望有大牛帮忙解析这个数据,还原成 recast 用的导航网格。Unity版本是 5.5.1,Unity 4.2版本的解析代码是有的,新版本格式变了。
首先用 NavMesh.CalculateTriangulation 获取所有的顶点和索引数据,这个是完整的、构建过的NavMesh,包括了多边形信息(最大边数为6边型的凸多边形),但是这个数据中所有的多边形是不共边的(多边形的边是重复数据),所以需要首先合并重复的边,可以利用 RacastNavigation提供的代码,基于 rcBuildPolyMesh 增加一个修改版本(比如叫:rcBuildPolyMeshBySeparatePolyTriangle),目的是合并已有的多边形的重复边,这一步结束后,就可以借用 RacastNavigation 剩余的构建流程:
1)创建 NavMesh并使用以上的 PolyMesh 初始化 (dtCreateNavMeshData, dtNavMesh::Init);
2)根据已有的 NavMesh 更新包围盒;
3)根据现有的 NavMesh 将每一个 Tile 写入文件(这之前可以写入自定义的文件头信息,方便读取);
4)服务器读取存储的数据,并用来初始化生成 NavMesh,就可以 findpath 了。(也可以将这个数据导入 RacastNavigation 的 Demo 中查看可视化情况)。以上 1-4 是RacastNavigation示例中构建流程的一部分,重点是 rcBuildPolyMeshBySeparatePolyTriangle 这一步合并多边形即可。这么做的好处是,导出的 NavMesh,跟 Unity 里构建的,多边形信息是一模一样的。想要支持 DetailMesh,估计还不行。
另外,服务器直接用可能还有点问题,如果 Unity 导出的数据很多细长的三角形,那么RacastNavigation的结果会和 Unity出现很大的差异,需要稍微修改下RacastNavigation的代码 。
我之前记录了个不太详细的描述,仅供参考:http://www.cnblogs.com/yaukey/p/recastnavigation_unity_optimize_visible_result.html
该问题来自UWA问答社区,感谢 Yaukey提供了回答,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/59f93d2aa740da296dd03662
渲染
Q4:目前我在用的Unity版本是2017.1.0f3 for MAC,在iOS平台下Bake Environment Reflections的时候丢失HDR信息,操作步骤如下:
1、当我使用Standalone Platform时,我使用了一张带有HDR的SkyBox CubeMap贴图(默认压缩方式BC6H),通过它生成的ReflectionProbe-0.exr会给物体带来明显的一个高光效果,如图所示:
2、当切换到iOS Platform后,再次用同样的SkyBox CubeMap贴图(压缩方式为PVRTC,或不压缩RGB24 bit都试过)烘焙ReflectionProbe-0.exr时,发现这个效果消失了,如图所示:
3、此时,如果我把之前的那张Standalone下面生成ReflectionProbe-0.exr替换过来,可以获得跟Standalone下一样的高光效果。把该工程发布到iPhone 7P上运行,效果与“步骤一”中一致。 说明ReflectionProbe-0中的HDR信息得到了保留。但是我注意到,在iOS Platform下面,ReflectionProbe-0的默认压缩方式是PVRTC或RGB 24 bit,这两种方式都无法保留HDR信息。如图所示:
4、通过对比两张ReflectionProbe-0.exr贴图,发现他们的文件大小是不同的,Standalone下面的贴图要大一些。如图所示,请问这是Unity的Bug吗?
我在此上传了示例工程:exr_EnvRef_iOS.zip,默认是PC Standalone,需要手动切换一下Platform,切换后重新Generate Lighting。
用题主的工程文件尝试了一下,的确是出现同样问题,并且在Android平台也是一样。目前看来只能判断是Reflection-Probe烘焙时使用了两套不同的操作。
再提供一个线索,用renderdoc->texture viewer可以查看像素值:
Standalone(PC)
Android
从上图可以看到相似区域Standalone比Android的烘焙结果数值要高出许多。
该回复由UWA提供。
我在Unity 5.6下发现效果是一样的,结论和题主一样:Mobile平台下Bake出来的Probe是LDR的。他是通过放大亮度来做的,但其实有更简单的办法:看高mip就行,首先是PC模式下Bake的。
然后是Android下Bake的:
出现亮度区别的原因是PC上有亮度>1的像素(一般是太阳之类的) 然后在卷积的时候就值大一些;而Android下就相对值低 在mip=0的情况下大家都是0-1看不出(显示时候截断了) ,目前的结论就是在移动平台Bake的Probe依然是LDR的,这是有问题的…临时解决方案就是在Standalone上Bake完复制过来。
感谢钱康来提供了以上解答。
题主补充:有了新的发现,基本上可以确认是Bug了。两张reflectionProbe-0.exr贴图的确不一样!除了尺寸之外,切换到iOS平台后生成的exr丢失了高光部分的HDR信息。
这两张图片初看没什么不一样的:
调整exposure,令exposure变为-5 (我用的是openexr,也可以用ps直接调整曝光度):
可以看到上图有两个非常明显的光斑,这个光斑的亮度非常高,因此会在物体上产生非常强的亮度。然而,在iOS Platform下面进行烘焙的时候,Unity把这个信息给丢失了。但不是所有的exr都会出现这样的问题。只有那些具有局部强光源的HDR图片才会出现这种情况,例如楼主用的那张,还有这张图片:
http://gl.ict.usc.edu/Data/HighResProbes/probes/grace-new.exr
该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a00094ddd5175ca6efb814f
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站(answer.uwa4d.com)上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(仅限技术交流)