【GAD翻译馆】移动VR游戏开发(第二部分)
译者:刘鸿(lewis2012,251423807) 审校:王玥亭(玥亭)
在移动VR游戏开发(第一部分)中,我们讨论了在开发虚拟现实游戏《Pocket Games》时,所用到的工具和技术。我们使用两款虚拟现实游戏Castaways VR和Duel VR展示了这一点。
我们将继续
严格的要求
“正如我前面提到的我们必须努力实现一个很好的游戏帧周期。”对于像Oculus Rift和HTC Vive这样的PC VR来说,需要90帧每秒。这给了开发者11毫秒的时间来完创建一个游戏帧。对于像Oculus Gear VR这样最流行的移动虚拟现实平台,你需要60帧/秒。这给了开发者大约16毫秒的时间来创建一个游戏帧。当然,因为我们谈论的是VR所有这些框架必须被绘制两次。
你可能会认为,因为16毫秒比11毫秒的时间要长得多,而且在移动虚拟现实中实现起来很容易。但事实并非如此。虚拟现实兼容的移动设备的性能与虚拟现实的PC是不可比的。
Gear VR的其他限制:
50000 - 100000六边形
50000 - 100000个顶点
50 – 100 openGL绘制次数
建议使用128 MB的纹理(最大512MB)
动态的光照和阴影
Oculus框架
因为我们的平台是Gear VR,我们必须讨论这个框架。在整个VR系统的背后。Oculus已经做出了很多努力,使开发者通过使用这个工具变得更容易。我将谈谈我在开发两个虚拟现实游戏时学到的一些技巧。
首先,分层系统。在实践中,这就像我们看一个计算机屏幕一样,其中有多个窗口,这些窗口是整个图像的组成部分。我们看到的是由多个层基本上是发生在这里。我们可以控制其中每个元素的位置和分辨率。例如,更高的分辨率可以被用于标签,因此它们是可读的,而使用较低分辨率的元素来使游戏场工作正常。
我们可以用它来显示HUD,在Castaways VR中,我们也用它来显示加载界面,直到所有的东西都加载了。
另一个非常好的是中间帧生成技术(Asynchronous Timewarp),我们非常喜欢它,因为它不需要开发人员进行大量的工作。关键是,我们不需要立即显示图像,而是一个平面渲染,然后在显示给用户之前,传感器被设置,所以一切都出现在他们应该出现的地方。这可以帮助防止帧延迟,并产生一个更恒定的帧率。然而,也有一个缺点,因为它移动了框架,如果我们使用固定在玩家视觉上的任何元素,如果我们没有足够的优化,它们就会滞后。但是,我认为每件事都有它的缺点吧。
异步空间扭曲(Asynchronous Spacewarp)是中间帧生成技术(Asynchronous Timewarp)的兄弟。用这个工具,我们会拥有魔法,不幸的是,它的完整版本不能用于移动虚拟现实的开发。这就工具通过编辑游戏帧来进一步处理帧平滑过程。在运行时,它监视我们显示的内容,以及显示的动画。因此,如果我们没有提供一个新的帧,工具根据之前的数据推断它,移动对象并生成缺失的部分。它基本上产生我们的中间帧。这意味着,我们可以以每秒45帧的帧率流畅体验游戏。但是这个魔法是有成本的,它可以产生的场景是有限的。例如,非常相似的外观纹理会产生奇怪的结果。所以,如果我们使用这个工具,我们仍然需要注意。
在这个框架中,CPU和GPU性能也是有限制的。这使我们不能使用比限制更多的资源。这对移动设备非常重要,因为我们必须注意电量消耗,但最重要的是热量。如果我们不限制性能,电池可能在约10-15分钟内耗尽(Galaxy S7)。我们必须找到限制性能和流畅的游戏之间的界限,这需要一些时间。
在Oculus的网站上有大量的文档。我强烈推荐阅读它,并在深入开发之前了解这个框架。如果计划过程不够仔细,我们会错过这样的工具,如果使用得当,你的开发过程会轻松很多。
假设我们的游戏快完成了,准备发布,但我们的游戏并没有60帧每秒。我们怎样才能做到这一点呢? 我们把整个代码,拖到“optimize.exe”, Mac OS的用户不能运行exe程序。这个自动化过程需要大量的手工修改。这就是我们将要讨论的,我们如何优化Castaways VR。
简单地说,当CPU告诉GPU“嘿,这里有纹理图片,画出它”。我们可以通过一个对象并把它交给GPU来绘制它。GPU可以很快地绘制它,比CPU能提供指令的速度要快得多。
这就是问题的开始。如果我们总是期望CPU告诉GPU来绘制,那要花很多时间。同时CPU也有其他的任务,比如运行游戏和操作系统,这些任务不能仅仅因为一个绘制调用(DrawCall)就停止。因为这是虚拟现实,有两个眼睛所以每次渲染需要绘制调用(DrawCall)两次。
这有一些解决方案,但我们必须把它考虑在内。如何减少绘制调用(DrawCall)的次数?我们如何解决这个问题?
有一个简单的解决办法,也许我们画的东西太多了,让我们少画点,这可能会给游戏带来问题,比如看不到场景中的元素,所以我们需要另一个解决方案。
如果我们我们将绘制内容分离,并将多个分离的对象混合到一个绘制调用中,会怎么样呢?这可以工作,但也存在一些问题,特别是在开发的早期阶段。如果我们把东西混在一起,设计师会告诉你,有些东西需要修改,开发人员可能会把自己的头发弄掉。因此,如果我们这样做,我建议在开发的后阶段做它,当最后设计关卡的时候。
另一个解决方案是批处理。这会将对象放入一个批处理中,这样就可以将这些对象组合在一起。这与我们手工做的方法非常相似,它是在运行时完成的。然而,当我们可以使用这个的时候,有一些限制。一种是静态批处理。顾名思义,这只适用于静态对象,在游戏过程中不能移动或修改。这缩小了它的使用范围。积极的一面是,这只在运行时使用内存,现在不是问题。另一种是动态批处理,可以批量移动对象。但这是有可能的。顶点属性,材料属性必须被考虑,因为它不能处理所有东西。由于这是动态的,这必须在绝对运行时进行,这将导致CPU的巨大负载来处理。在极端情况下,它甚至会使性能恶化。调试也是一个非常头痛的问题,如果有些事情没有解决,需要花大量的时间来找出原因。
透明材料使移动设备上的性能表现的很糟糕。原因是移动GPU使用一些硬件优化的渲染程序不能处理这类材料。同时,绘制这些透明材料是一项艰巨的任务,为GPU。这会导致性能下降,在所有平台上,最明显的是移动设备。
这些元素的最终序列也是一个有趣的话题,你必须回答“什么在前面”。这被开发人员称为深度冲突(z-fighting),指的是Z轴。当游戏场景看起来工作的完美,我们精确地计算材料的位置。当我们看这些材料时,材料的边缘彼此相交。如果可以的话,我们尽量避免在移动设备上使用这个整个话题,尤其是在移动VR上,这种影响甚至更糟。如果不是100%强制性的话,就不要使用透明材料。
不幸的是,我们不得不使用透明的元素。
那么我们在Castaways VR是如何做的呢?
我们使用了Sprite表,它是三维环境中的基本图片。如果我们要在太空中展示一些东西,我们需要把它放在某些东西上。最简单的解决办法就是拿一个立方体,把它画在上面。问题是,这取决于我们展示的像素是透明的。这些像素对游戏没有任何影响,但仍然需要计算,因此这会使性能更差。
生成一个合适的网格可以解决这个问题,这是我们在Castaways VR中所做的优化。Unity为我们生成这个网格,不幸的是,结果往往是灾难性的。出于这个原因,我们使用了一个插件,它有大量的设置,使我们能够调整到正确地设置。最重要的是模型细节与未显示像素之间的比例。我们必须找到正确的黄金比。
如果我们生成这些设置,将会有大量的网格和大量的材料,所以我们最终会得到大量的绘制调用(DrawCall)。这导致性能变低,我们将回到我们开始的地方。为了防止这种情况发生,我们使用了一个名为“Sprite terminator”的插件用于多个函数。我们制作了纹理图集,用其中的几个纹理,把它们拼成一个图像。使用这种方法,我们必须确保在图集上留下尽可能少的空白。
我们在网格上做了同样的事情。Castaways VR的第一个场景是由4 - 5个大的网格绘制而成,而不是最初的300个。我们也去掉了透明的纹理,我们转而使用了alpha测试。在这里,透明度仍然得到了支持,但不存在50%透明的东西。缺点是我们不能创建漂亮的圆角。结果是,纹理有这些块状边缘,但运行速度很快。
下一步要做什么?
在我们做了所有这些事情之后,我们还能做些什么来确保运行更加流畅?我们给精灵(sprites)用了更多的网格。我们创造了更多的atlases网格。我们创造了更小的atlases。我们将其转换为'alpha to coverage'阴影,这与'alpha mask'非常类似。前者比后者要多一点信息,它有一些透明度,可以在相同的性能下显示出更好的边缘。
完成了一些手动剔除,这是为了确保游戏中的摄像机不能看到的元素不被渲染。因为我们在Castaways VR中有固定点,我们可以在每个点上看到所有的东西。基于这6个点和从它们可以看到的东西,在CPU和GPU的性能上,如果需要时我们给予更多的能量,如果不需要的时候我们减少能量。例如,在一个水下场景,我们展示了很多效果我们需要更多的能量。这一调整基本满足了我们的对性能的要求。
(Kristóf/程序员)
像素过渡绘制
“我们几乎达到了我们期望的每秒60帧。在此之前,主题是,关于CPU承载着过多任务,所以我们把大部分的任务分配给了GPU。这是我们的策略,但过了一段时间,就连GPU也无法应对这些任务。我们怎样才能使它变得更容易呢?
我们可以先减少过渡绘制。什么是过渡绘制?过渡绘制是一个像素的内容被改变多次直到它达到最终状态。让我给你们举个例子,如果在灌木前面有树,我们画灌木,然后树我们就浪费了隐藏在树后面的像素来画出了灌木。
我们如何消除这个?幸运的是GPU帮助我们使用早期的像素丢弃技术,这不是完全自动化的,所以我们必须手动设置一些东西。我们必须手动设置渲染的顺序。在这里,我们首先画出灌木和树,最后是地面、小山和天空。我们把它放在上面,这样GPU就可以知道这些像素不应该再次改变状态,不需要再次绘制。这样我们可以节省一点性能。
还有一个虚拟现实技术我想和大家分享。
混合摄像机系统
在虚拟现实中,我们每个人的眼睛都有自己的画面,这样我们就能看到一些非常准确的东西,如果有什么东西在我们近处移动,它看起来很好。但如果我们看远处的物体,三维效果并不奏效,从10米左右开始效果就不够好了。所以,要引入第三个摄像机,就好像我们有第三只眼睛一样。有了这个第三个摄像机,我们只用它渲染远处的物体,然后把近处的渲染图像合并在一起。这样,我们对于远处的物体我们就节省了一半的绘制调用(DrawCall)。不幸的是,这只是一个想法。我们不能使用它,因为我们的界面是由远距离的大网格制成的,这有悖于我们的摄像机系统。所以我们把整件事都丢了。但如果你用它来做你的项目,让我们知道,我很乐意看到它工作。
(Péter /程序员)
但是我们如何发布呢?
因为我们是在Oculus平台上开发的,很明显在Oculus商店里发布。我们需要在商店列出现什么内容?那么有一个很长的规则列表。例如,在Gear VR耳机上有按钮,每个按钮都有关于它可以执行哪些功能的规则。还有关于商店页面上的描述的长度,游戏视频和图像的分辨率,格式和内容等等。所有这些都可以在Oculus的网站上找到。我建议尽早阅读这个,所以你不要把时间放在不能发布的地方。
另一个是性能测试。这就是我们进行长期优化的原因。在这个阶段,他们在多个虚拟现实设备上进行游戏测试,看看帧速率是否真的不会低于60帧每秒。如果是这样,应用程序将会被拒绝。前几次Castaways VR上的性能测试失败了。这本身是一个艰难的测试,但是测试的结果并没有使它变得更容易。结果表明,除了具有最低和最高性能的设备外,游戏运行良好。我们真的不知道该怎么想。我们给它多了几个镜头,并发布了它。Castaways VR是我们的第一个VR游戏。我们学到了很多,当我们第二次做The Duel VR时候,优化过程要快得多。
内容测试还需要在游戏中仔细查看内容是否合适,质量是否足够好。在这个阶段,他们检查游戏的描述和价格,并建议在需要的时候进行修改。在所有这些测试之后,我们可以把游戏发布在商店中。但是在商店的哪里呢?这个商店有多个类别,你的游戏可以发布在被称为“Gallery Apps”这个有趣的类别,这是未完成的,早期的访问,都是没有优化的,甚至是短的游戏。令人惊讶的是,我们的开发者并没有说我们的游戏被列在什么类别下。在内容测试中,决定购买Oculus。Oculus的支持团队非常棒,如果我们有任何问题,他们会迅速回复帮助我们。所以,如果你遇到了问题,要自信地联系他们。
确保你的游戏具有独一无二的创新。这将使你的游戏脱颖而出,取得成功,并将这个职业推向更高的水平。
原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权。