技术分享连载(七十二)

简介:

渲染

Q1:我们是手游项目,想对场景中的静态物件做一个遮挡剔除,不知道Unity自带的Occlusion Culling对性能优化的提升有多少呢?我们用Unity官方例子测试,启用Occlusion Culling后发现DrawCall、Triangle几乎没有变化。另外也想获知,Occlusion Culling的数据能否像NavMeshData那样可以动态加载呢?谢谢!

Occlusion Culling在使用后具体能提升多少,这个其实是没有明确数值的,甚至可能不升反降!这个只能题主在自己的项目中进行尝试。

一般来说,Occlusion Culling功能特别适合第一人称或第三人称跟随的平视角相机(比如传统意义上的MMO等类似游戏),且适用于在场景中存在大量的遮挡情况。因此,在城市街道漫游、峡谷漫游等特定场景中,比较推荐开启Occlusion Culling功能。

但是Occlusion Culling功能本身存在一定的性能开销,因为需要每帧均遍历烘焙的Cell来明确哪些物体需要或不需要渲染,所以场景中Cell越细,那么其查询开销也就越大。因此,如果场景中本身没有大量的遮挡关系,那么开启Occlusion Culling功能后,其节省下来的渲染耗时可能抵不上其Cell查询耗时来的大,这样就得不偿失了。

下图为我们优化过的一个案例,项目中开启了Occlusion Culling功能,由于场景过于复杂且Cell也烘焙较细,所以可以看到其Culling中的WaitingForJob耗时达到了33%。
请输入图片描述
因此,我们尝试将项目中的Occlusion Culling在运行时关闭,并在Profiler中直接查看关闭前后的对比结果(下图),可以看到,Rendering中的Draw Call、Triangles并没有变化,但其Culling开销却大幅下降。这说明,在该项目中,Occlusion Culling虽然开启但并没有起到效果,反而大幅增加了CPU端的Culling耗时。
请输入图片描述
综上所述,Occlusion Culling功能仅适合于特定项目、特定场景来进行使用,并且建议在使用前后,项目组应该多加对比,反复查看其加入后是否确实带来性能提升。

最后,Occlusion Culling的Data目前并不能动态加载,只能随场景来进行加载。因此,可以尝试创造一个拥有Occlusion Culling Data的“空场景”,然后通过LoadLevelAdditive方式来进行加载,从而来达到“动态”加载的效果。

此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/596c93da2832ee102d2ac18e
如您对该问题仍有疑问,可以转至社区进行进一步交流。


内存管理

Q2:通过Profiler.GetMonoHeapSize()获取到的堆内存,在操作UI的时候,打开某个节点比较多的UI界面,根据上面接口取到的堆内存会突然涨6~8MB,但是Profiler取不到这个数据,该怎么办呢?我不是固定打开某个界面,而是随机出现在某个界面上,这样的问题该如何入手呢?

Mono总体堆内存一次性涨6-8MB是比较正常的。Mono内存并不是随用随分配的,而是当其发现不够用时,一次性从系统中获取一段连续的内存。在游戏运行一段时间后,这个值一般是8MB。所以,题主遇到的情况很有可能是在连续操作UI界面时,Mono发现堆内存不够用了,于是就有了题主观察到的内存分配。

此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/596f3a85e7b53b286095384d
如您对该问题仍有疑问,可以转至社区进行进一步交流。


动画

Q3:我写了一个顶点动画的Shader,对物体顶点位置进行了修改,使其能够跟随相机移动,并总是出现在相机前面。当游戏运行后,开始时物体能够正常显示。相机在场景中移动一段距离后,物体便不再显示,但相机换一下朝向,物体又能显示。目前排除了面剔除的原因,在Shader中已经关闭了Cull(Cull Off),请问还可能是什么其他原因呢?

消失的原因应当是Unity的Frustum Culling引起。因为顶点动画是在shader中修改的顶点位置,而Frustum Culling是根据顶点修改之前的Mesh的bounds进行的,因此随着相机移动,Mesh实际已经出了Frustum的范围。最简单的解决方法是直接将Mesh的bounds设置足够大,让Unity始终不对其进行Culling:
mesh.bounds = new UnityEngine.Bounds(transform.position, new Vector3(float.MaxValue, float.MaxValue,
float.MaxValue));

此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/596c8cb52832ee102d2ac18c
如您对该问题仍有疑问,可以转至社区进行进一步交流。


GPU

Q4:我使用SystemInfo.graphicsDeviceName获取的GPU信息不太详细。比如ARM系列的Mali,T880 MP2与T880 MP12相差甚远,但是只能获取到T880,无法获取MP的信息。各位是否有办法?

对于获取GPU名称信息,在Android的Java层中可以利用API:GLES20.glGetString(GLES20.GLRENDERER)获取显示设备名。可以尝试在Unity中利用AndroidJavaClass(https://docs.unity3d.com/ScriptReference/AndroidJavaClass.html)来调用该API,尝试获取更详细的型号。

如果获取GPU名称的目的是判断GPU性能,可以看下SystemInfo中其他graphicsDevice相关的GPU性能信息是否够用。

此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/59688ccda5c647ad018763cf
如您对该问题仍有疑问,可以转至社区进行进一步交流。


物理模块

Q5:两个挂了Collider的物体,一个物体挂了Rigidbody,去碰撞另一物体,为什么每次OnCollisionEnter这个函数在实际还没有碰撞的时候就调用了呢?如下图,这时OnCollsionEnter已经被调用,但从图上可以看到两物体实际还没有接触,这个函数调用之后才会真正碰撞在一起。
请输入图片描述

物理系统在FixedUpdate中触发,包括OnCollisionEnter。而FixedUpdate早于Frame Rendering,因此碰撞实际已经发生,只是画面还没更新。其实在运行时这点时间差几乎应该可以忽略。






原文出处:侑虎科技
本文作者:admin
转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
目录
相关文章
|
JSON 安全 JavaScript
开源分享|速进!这些开源项目助你玩转世界杯
为了帮助大家找到更好的世界杯打开方式,OpenSCA项目组搜罗了一些与世界杯相关的开源项目。一起来看看吧~
212 0
开源分享|速进!这些开源项目助你玩转世界杯
|
前端开发 JavaScript 程序员
我们相约,这份学习指南请您收好。
我们相约,这份学习指南请您收好。
崮德好文连载 - 个人如何成长?
毕业后刚开始工作的工程师,对技术一定是充满热情的,也是非常专注的投入工作。但是工作3,4年然后跳槽一两家公司后,渐渐的就迷失了,感觉技术有了一定提升,比刚毕业的大学生,确实有点优越感,但是比下有余,比上不足,感觉差距很大,关键是单纯提高技术能力,似乎永远赶不上优秀的前辈,这样的困惑完全可以理解。我想聊聊这个阶段的工程师,该如何成长。
|
中间件 Go 流计算
为“程序媛”点赞 “阿里中间件性能挑战赛”完美收官
由阿里巴巴集团主办,阿里云天池大数据平台承办的第二届“阿里中间件性能挑战赛”吸引了1946支队伍报名参加,不但有来自413所知名高校的学生和科研人员,还有来自40余家企业的社会选手,这表明,“阿里中间件性能挑战赛”已经成为影响力巨大的重要技术赛事。
5270 5
|
API 图形学 iOS开发
|
缓存 API 图形学
|
缓存 索引 容器
|
前端开发 API 图形学