控制中的程序中断:补救经验的教训

今年夏天,在GDC上,资深视觉特效师Remedy Johannes Richter谈到了工作室最新游戏《神秘动作游戏Control》如何实现程序中断。



在演讲中,他关注了构建许多游戏内效果的基本原理或粒度原理。该工作室如何实施具有现实可破坏性的大规模系统,其自身资源和平台性能面临哪些局限性,进行了哪些优化以及从所有这些中学到的经验教训-进一步在材料上。







因此,首先要谈谈工作室面临的挑战。



游戏发生在野兽派风格的政府机构大楼内,该大楼具有一些超自然的特征,例如活动墙。



总部的结构应该看起来很可信,因为这是一个政府机构,雇用数千名执行日常任务的服务人员。桌子,电话,杯子,多功能一体机-所有这些都是您希望在工作场所中看到的上班族的通常属性,通过它们的存在,它们可以定性地讲述这个地方的故事。野蛮主义意味着大量的混凝土,但不仅如此:这里既有木材又有玻璃,它们为特殊服务的建筑创造了最合适的外观。







关于破坏,首先要考虑的是触觉。开发团队的任务是组织一个丰富的交互式环境,该环境立即带来可以与其中几乎所有内容进行交互的感觉。







显然,工作室在工作中面临某些限制。与对象的交互必须看上去逼真。玩家应该在销毁方面有一定的行动自由,但不是无限的,因为游戏的可能性取决于平台的最终性能,内存和对人工智能的要求。同时,负责实施可破坏环境的任务的团队非常小,在工作中也必须考虑到这一点。







因此,游戏中的可破坏性基于粒度原理。它也是摄影中许多特殊效果的基础。其含义是自然是无法量化的。它是由各种各样的物体(从大到小,从大型固体到灰尘和烟雾)制成的连续画布。如果屏幕上没有反映出任何内容,则整个图片将无法工作。



在游戏引擎中,可以在三个不同级别的细节中实现此原理。它们上的物体以刚体(刚体),其零件,道具的零件,道具本身和环境的形式呈现。在这种情况下,后者是一种静态网格,交互式对象可以与之碰撞。网格粒子,实体层次结构和材质贴花为对象提供了特定图层上的更多细节。因此,我们从固体对象继续前进到其碎片,然后再移至碎片。最后一层是粒子本身。粒子精灵,余烬粒子,沙子等在填充这些渐变中起着重要作用。







上面的屏幕截图显示了一个静态环境。它看起来很空,尽管这里有一些细节:例如,在背景中您可以看到楼梯的栏杆。







当我们开始用可以直接交互的对象填充空间时,感知会发生变化,这一点令人惊讶。







对于Remedy中的工作流程,它实际上是微不足道的。环境美术师提供关卡几何模块和用于组装的道具,之后,VFX部门设置了装备和电影破坏动画。最后,将结果发送到Remedy自己的引擎Northlight。



有必要决定一种一切工作方式的方法,然后团队决定采用一种程序性方法。



这是什么意思?



程序方法是基于规则的数据处理和解释。







有关游戏世界的信息由包含有关材料的元数据的模型表示。因此,您可以设置例如长凳的座椅由织物制成,基座由混凝土制成,植物实际上是植物。定义材料后,您可以为每个材料制定有限的规则集,确定对游戏中可以执行的所有动作的反应。例如,当从植物中射击时,树叶会飞散,混凝土会碎成碎片,金属管会变形,水会从中喷出。然后,所有数据都被重定向到引擎,并且它已经对每个交互做出了适当的反应。







那么为什么要程序破坏呢?



因为需要快速一致地采取行动,所以在明确定义的条件下可以预期行为。游戏中涉及数百种资产。在上图中,您可以看到构成房间,墙壁,圆柱,楼梯,栏杆等的各种块。它下面有各种道具:桌子,椅子,花瓶,植物,计算机,电话。为了销毁如此众多的物体,只选择了一个1-3人的团队。因此,有必要预先确定世界运作的模式:如果某个物体以某种方式受到影响,则有必要按照指定销毁某种给定材料的方法所规定的精确破坏它。







因此,有必要根据材料设置某种行为。这样,当您在树上射击时,它会飞成碎片。或者,如果您在玻璃上射击,它会碎成碎片。在这种情况下,颗粒和贴花还必须根据对象的组成以某种方式起作用。







每种材料都有自己的断裂几何形状,由不同的级别定义。在示例中,我们看到了一块栏杆,其底部是混凝土,然后是金属支撑,最后是木头。从左到右,各阶段显示为中断:



  • 级别A显示混凝土断裂。这里没有贴花,因为裂缝很少。可以看出,支架稍微弯曲了。
  • B级。金属消失了,但剩下的碎混凝土和木材仍然存在。
  • C : , .


现在,让我们想象一下,我们碰到了对象的某个角-那么它应该不会完全破裂,而只是部分破裂。







因此,在“控制”中,有实体是单个对象。但也有通过链接连接的详细信息。这些是所谓的复合碰撞可以分离的相同刚体。







在初始化期间创建零件,共享一个通用对撞机,然后将它们作为一个零件移动,直到它们断裂。它们通过彼此接触的那些表面彼此连接。







让我们谈谈连接。它们基于元数据在几何层次结构中创建。实体通过一种铰链相互连接-例如,在门或抽屉的情况下。它们又可以被冲动的力量动态破坏。







化合物具有特殊的破坏机理。它们不会与物体破碎-也就是说,如果您在门上开孔,门将仍然是一个完整的物体,通过内部连接固定在一起。因此,如果您破坏了父块RB1,门将不会从铰链上掉下来:门的一部分仍将附着在开口上,不受撞击的影响。而且,中间带有孔的门仍可以按预期方式打开和关闭。因此,开发人员希望避免出现物体完全破裂的情况,而不管打击的位置和作用力如何,就像某些游戏一样。







Northlight的专有模拟运行破坏逻辑并确定哪些事件和粒子对其做出反应。然后,NVIDIA物理引擎对刚体进行建模,并尝试使其适应游戏的约束。







破坏本身如下实现。我们有一些输入几何。有时有必要事先准备模型,设置胶粘几何形状并确定在哪些情况下哪些零件可能会断裂。然后将模型发送到Houdini并在那里进行处理。 Houdini中的Destruction是相当大规模的HDA设置,它可以执行基于材料的反应并将数据写入内存。有时,我必须手动修复和设置一些物理元数据以确保设置正确,尤其是在连接时。然后,所有数据都传输到引擎,在引擎中用于创建游戏世界。







Houdini中的销毁工具看起来像这样。假设我们有一个具体的块作为输入。有必要确定哪些区域会破裂并固定材料。在这种情况下,块将根据为混凝土设置的规则执行销毁,管理并在渲染几何体和碰撞方面创建不同的层次结构。然后,您需要确保在设置的预算和样式内完成建模。之后,您可以将模型导出到引擎。







引擎中看起来像这样。您具有一种层次结构,其中包含有关A,B,C等层的信息。这包括材料的名称,对象是否为静态,连接上的数据,它们的类型等等。层次结构由级别表示,物理属性根据材料的名称而有所不同。如果正确指定名称,则引擎将处理物理过程。稍后我们将讨论名称问题。







以上是一个可靠的模拟场景。杰西向她周围的物体射击,然后爆炸,从而实现了破坏物理。







由于可破坏的环境是一项耗费资源的事情,并且控制台和PC都有自己的性能限制,因此该团队面临着优化系统以免设备超负荷的任务。



由于有必要将其设置为一定的性能预算,因此在屏幕上将活动实体的上限设置为200,因此该实体之外的所有对象都会消失。



在涉及许多快速移动物体的事件中,碰撞会有延迟,因此系统有时间进行所有计算。



还为未使用的物品实现了睡眠模式。例如,如果一块混凝土块掉落到地板上,没人会期望它像球一样开始跳跃-因此它可以很快“入睡”。这适用于游戏中的许多物品。出于相同的原因,它们可以彼此堆叠,并且以相同的方式静止放置。



另外,物品之间的间隙被颗粒填充。因此,当物体被破坏时,在其周围形成灰尘或碎屑。







游戏中的所有内容都是系统的且由事件驱动。存在以下粒子事件:



  • 子弹撞击,其结果取决于材料;
  • 断开两个部分之间的连接;在这种情况下,会发生刮擦,释放出颗粒;
  • 完全破坏物体,导致其分解为颗粒。






上面显示了编辑粒子的过程。在游戏中,您可以放置​​特定的粒子系统,然后进行更改。在这种情况下,火花形成的频率仅发生变化。有趣的是,您可以实时更改它并立即获得即时反馈,然后再次播放并查看效果如何。通过这种方式实现的快速迭代循环可让您完善此类内容,直到它们正确显示为止。







粒子的另一个特征是标准建模。团队有时需要使用带符号的距离字段(SDF)。因此,可以确保物体不会掉落到地板上,这看起来非常奇怪。







在上面的示例中,可破坏对象是粒子与固体的共生。这就是我们所看到的。由于填充了粒度梯度中缺少的间隙的附加颗粒层,爆炸在空气中产生了灰尘。







最后是贴花材料,游戏中有很多贴花材料,它们是动态生成的。基本上,它们只是应用于对象以创建破坏外观的纹理。



如果有东西破裂,物品上会出现带有裂纹图片的贴花纸。它们通常是在Houdini或类似版本中创建的。在“控制”中,根据材质动态选择所需的贴花。它还有助于利用静态几何的相当大的一部分。如开始所示,我们周围总是有许多静态对象,这些对象也可能会受到某种影响,必须予以考虑。







这就是它的样子。如果您打碎地板,则多边形本身将保持不变,但是随着贴花外观的出现,其外观可能会发生很大变化。值得注意的是,它们使用起来非常经济有效。







因此,我们有颗粒,固体和贴花。在这个例子中,我不得不花一些技巧,因为一个简单的爆炸工具不会产生那么多贴花。现在,杰西“抛出”一个可能在地板上留下凹痕的物体。同时,地板仍然是静态多边形,但是由于贴花纸,撞击痕迹仍然保留在地板上。







我们还将讨论自定义道具的主题。灭火器,计算机,灯等有很多游戏内物品散落在周围,无法完全通过程序生成。环境艺术家仍然必须手动为其设置效果。但是,从它们的存在来看,游戏中的世界看起来更加丰富和多样。



那么,工作室从Control中学到了什么?



在此需要注意以下几点:



  • ;
  • ;
  • ;
  • .






首先是几何的质量。输入几何形状不一致可能是由于缩放比例和方向不正确,也可能是由于材质分配不正确。有时,网格质量可能太低,这也会对结果产生不利影响。还可能发生的情况是,当您破坏一个对象时,您会意识到其中没有任何东西,这是错误的。为避免此类问题,有必要改善输入数据,标准化整个几何图形管道,以便在导出过程中,系统会在某些内容不符合标准且需要更正时发出警告。这将有助于避免不同部门之间不断出现反馈循环,以寻找问题发生的确切时间。



此外,最好有内置工具,以便您可以对对象建模并立即查看销毁后的外观。显然,这带来了用更好的界面来制造更多工具的挑战,但这是值得的。







我们习惯给不同的事物起名字。但是问题在于这些名称可能不正确。例如,在“控制”中,“混凝土”的材料有17种不同的名称,这不能归咎于任何人,因为总会有人为因素。里希特的建议是完全放弃命名标准。最好只有一个元数据API。这样,无论艺术家使用什么工具来制作道具,都可以直接从那里将数据导出到引擎,而无需任何中间步骤。







下一个教程主要针对Houdini。最重要的是,通常在开始处理某件东西时,您会在过程中重做多次,制作一些附加组件,并且需要确保即使经过两年的工作,即使该工作工具可能已经更改了20次。这意味着您需要某种标准化才能使用HDA。这就是Remedy目前正在研究的内容:确保正确分发所有内容,以使您永远不会丢失该工具的任何版本,并始终有机会重复您过去所做的事情。



在此需要特别注意的是,当您创建自动化工具时,实际上您在使用的软件与手动完成所有操作的软件相同。只要它们具有相同的后端,一切都应该完全一致。







性能和测试是开发中最重要的方面。



最初,Remedy中的测试不是自动化的。在将新对象添加到关卡后,您必须手动检查它以检查一切是否正常运行。但是随后引擎中发生了一些变化,后端发生了变化,某些事物进行了优化,然后需要进行重新测试。这非常危险,因为您一定会忘记检查某些内容。简而言之,这不是最好的方法,导致潜在的错误累积。



第二方面是性能测试。长期以来,Remedy并未测量任何重要指标,例如帧速率或计算时间。因此,经常发现性能问题为时已晚。







首先,这里可以做的是改善性能指标。有必要确定哪些参数增加会更好或更坏地影响游戏,以便在优化和确定不可超过的预算时依靠此参数。



此外,自动化测试可以为您提供帮助,在其中您还可以更改输出以更好地演示引擎更改的影响。







您还可以识别性能下降并采取措施。例如,为了使其在大规模事件中,某些对象绕过破坏的中间级别,例如,从固体直接进入粒子。



另一个措施是根据预期负载对区域进行分区。这个想法是基于这样一个事实,即我们可以自行确定在哪些区域应用某些对策,以便在不必要时不将其应用到所有资产。例如,如果很快有手榴弹的敌人及时赶到杰西,显然该地点将有太多破坏,并且在他们的攻击过程中,加速破坏的过程会加速。



结果,我想指出的是,Remedy团队做了一项艰巨的工作,从中您可以得到有关环境程序破坏系统的实施和优化的许多想法。



All Articles