我正在为Gear VR构建我的第一个VR应用程序。这是一个基于媒体的应用程序,我正在构建以查看360度视频。
我正在使用Unity 3D构建应用程序,我已经实现了应用程序的所有功能,但仍遇到了一个主要问题。
问题:使用10-12分钟后手机会变热:我使用三星s6测试这个,因此我无法在我的应用上观看长时间的视频。 我非常清楚,在堆栈溢出时,我们主要讨论编码实践而不是像这样的问题,但我的问题是,我是否需要遵循任何编码实践来避免这个问题。
我已经通过在设备上启用开发人员模式并安装齿轮VR服务来检查CPU利用率水平来测试它,但是当我测试商店中可用的其他应用程序时,我的结果是相同的(其他应用程序播放的时间比我长)
这里的任何人都可以指出我正确的方向,以便我可以摆脱这个问题吗?以下是一些细节:
Hardware used: Gear VR (white version) + S6.
Software used: Unity3d with third party movie player
Feature: User is made to download/stream the video from URL video size varies from (100MB - 1GB).
Issue: Device gets heated within 5-6 minutes.
Solution tried: Lower down quality settings, Deactivating Anti aliasing, Writing scripts to lower down render scale & render viewport of the camera.
答案 0 :(得分:2)
根据您的评论,如果您怀疑手机在运行应用时的速度比从商店运行其他应用时更快,那么您可能是正确的,问题可能在您的代码中。
现在,玩游戏时手机发热的原因之一是由于处理器和图形芯片的工作需求较高。
因此,您可以尝试的是发现VR应用程序中计算密集度最高的任务,以便您可以更改它们,改进它们或直接删除它们。在这里,我将列出一些技巧来提高Unity 5中VR应用程序的性能,您可能会感兴趣。
首先应该尝试一些性能指标:
1-静态批处理
您的场景中可能有大量静态几何体,例如墙壁,椅子,灯光和永不移动的网格。在编辑器中将它们标记为静态。请务必将它们标记为lightmap static,以获得烘焙的光照贴图纹理。标记为静态的对象可以被批处理为一个组合网格,而不是对每个单独的对象进行绘制调用。 静态批处理有一个至关重要的要求:所有对象必须使用相同的材料。如果您有带木质材料的静态墙壁和带有钢质材料的静态椅子,那么墙壁将被分成一个绘制调用,其中一个组合网格,并且椅子在单独的绘图调用中,具有自己的单独网格。
2-纹理图集
如前所述,每种材料都会产生一次平局调用。您可能会认为木门和钢椅可能需要单独的材料,因为它们使用单独的纹理。但是,如果它们可以使用相同的着色器,则可以使用纹理图集来创建两个对象都可以使用的材质。纹理图集只是一个更大的纹理,包括所有较小的纹理。而不是几十种材料加载数十种纹理,你可以让一种材料只加载一种纹理。可以映射每个对象以在图集上的不同坐标上使用纹理。 您可以在艺术流程中手动执行此操作,但我发现Juan Sebastian的Pro Draw Call Optimizer非常有用。它会自动生成新对象中的纹理图集和交换,而不会弄乱您的资产。
3-动态批处理
移动非静态对象可以动态分批到单个绘制调用中。我注意到这是CPU密集型并且在每个帧上计算,但是是一个很好的优化。这仅适用于使用相同材质的顶点数少于900的对象。使用纹理图集为您的动态对象创建单一材质,并获得便宜的动态批处理!
4- LOD
LOD组是提高性能的廉价方法。使用具有多个LOD的资源,并为远离相机的对象渲染较低细节的几何体。当相机靠近时,Unity可以在每个LOD之间自动淡化。
5-填充,透支和剔除
这是一个我不太熟悉的话题,但值得关注:减少过度绘制,首先将最远的对象绘制到像素,然后将每个较近的对象重新绘制在顶部。这对于普通的1080p PC显示器来说不是什么大问题,但对于具有超高分辨率显示器的VR和移动设备来说这是一个重大问题。大量的透支与较大数量的像素相结合会导致填充率下降。纹理滤波是GPU中的关键限制指标之一。 一些解决方案是开箱即用的,具有遮挡剔除和平截头体剔除。 Frustum剔除不会渲染摄像机截头锥体外的物体。没有点你无法看到的渲染对象!遮挡剔除会消除被其前面的其他对象遮挡的对象。例如,门后面的房间可以完全省去。默认情况下,遮挡剔除适用于整个场景,但适当的关卡设计可以让你剔除整个游戏关卡。
LOD群组还可以剔除离场景太远的物体,进一步帮助减少填充物。
6-级别设计
如果您的游戏涉及从一个房间到另一个房间的玩家,则天真的解决方案将整个游戏放在一个级别。然而,缺点是内存消耗。每个房间中的每个对象和材料都会加载到内存中,即使它们不可见。将每个房间放在一个单独的级别,并在代码中智能地异步加载它们。
7-异步加载
在玩家进入下一个房间的门之前,加载下一个级别。不要使用Application.LoadLevel()同步加载它,因为这会导致游戏在加载时挂起。随着头部追踪暂时抓住,这将导致恶心并且对于玩家来说是一种可怕的体验。
而是使用Application.LoadLevelAsync()。您可以在Ocup Mobile SDK BlockSplosion示例中的StartupSample.cs下找到此示例
8-烘焙灯光
关闭实时阴影!接收动态阴影的对象不会被批量处理,并且会导致严重的绘制调用惩罚。
在PC上,您可以使用单个实时定向灯来获得漂亮的动态阴影。大多数现代PC都可以提供华丽的每像素阴影。然而,在移动设备上,您希望坚持烘焙照明,而不是实时阴影。使用高分辨率的硬阴影和柔和阴影烘焙您的灯光。
9-阴影
特别是对于高性能的移动体验,请跳回3D对象上的阴影的旧技巧。可以使用物体下方的简单2D四边形模拟半真实阴影,并使用模糊的阴影纹理。
10-光探针
使用烘焙照明时,动态对象看起来不合适,而静态对象看起来很棒。您可以使用光探针以便宜的方式模拟动态对象上的动态光照。
光探针是烘焙立方体贴图,可以在场景中的各个点存储有关直接,间接甚至自发光的信息。当动态对象移动时,它会插入附近光探测器的样本,以近似该特定位置的光照。这是一种在不使用昂贵的实时灯光的情况下模拟动态物体上的真实照明的便宜方式。
11-避免透明和多物质对象
像使用透明着色器的玻璃透视窗口这样的对象非常昂贵。通常使用具有灰尘或铁锈纹理的透明材料以及单独的基础漫射材料来为墙壁添加真实感。这种多材料α混合是昂贵的;每种材料都会增加一个平局!但请注意,多个纹理不是问题;使用多种单独的材料是昂贵的。使用一种材质和一种着色器可以将多个纹理与Alpha混合而不是多个单独的材质混合。
12-蒙皮网格渲染器
蒙皮网格渲染器通常用于具有动画装备的角色,使用物理(布娃娃体)或自定义动画(步行,跳跃等)实现逼真的网格变形。
悲伤的消息:皮肤网格渲染器不会被批量处理。场景中的每个角色都可以为每只眼睛创建多个绘制调用。我不知道如何解决这个问题。来源:https://blog.bigscreenvr.com/12-performance-tricks-for-optimizing-vr-apps-in-unity-5-9849bb6aefa7
答案 1 :(得分:1)
在尝试上述任何建议之前,请先确定您的应用程序是否受CPU或GPU限制。这可以在Unity3D的分析器中看到。
如果是CPU,您可以检查绘制调用,动态批处理等。
如果是GPU,请检查着色器,纹理填充率等
事先这样做会优化您的开发资源和时间,以获得最佳回报。