PhysX+REV解决载具音效拟真问题

前言
笔者曾经使用UE4内的车辆模块进行过载具模拟方案的验证。关于此部分的内容可以参考笔者之前的文章:以REV2为基础制作赛车引擎声
之前这篇文章主要侧重于介绍汽车的基础发声原理以及REV插件的使用。并未对游戏引擎中的相关设置和参数获取做详细介绍。如果参数的获取和调整不正常的话,我们就会发现游戏即使接入了REV,其声音表现也并不理想,甚至和REV内置的声音预览效果差距巨大。这是因为很多项目在开发阶段调整载具参数的时候并未接入声音,那么负责调整载具的同学就会以视觉表现为主,这就导致所有参数为视觉表现服务。结果就是车跑起来了,看起来很正常,但是内部和音频相关的参数则不太正常,所以声音模块接入以后的表现也并不理想。
本文将以PhysX物理引擎为例,介绍车辆声音模拟所需的参数有那些,以及这些参数应该如何获取和使用。以此和前文形成互补,从而完整的阐述如何在游戏中制作出拥有高互动性的汽车声音。
一、PhysX+REV制作载具模拟的效果及相关前置知识
PhysX是物理运算引擎的一种,常见的物理引擎还有Havok、Bullet以及UE5新出的Chaos。PhysX最早由AGEIA公司开发,现在已经被NVIDIA收购了。PhysX的功能其实非常强大,可以完成诸多物理模拟,几乎包揽一个游戏全部需求。本文不会涉猎那么广,我们这里使用的只有PhysX中的Vehicle Dynamics。选择它作为例子的原因是PhysX比较常见,UE4直接集成完整的PhysX载具模块,并暴露其大部分API接口,甚至提供基础演示DEMO。Unity中用来模拟载具的Wheel Collider使用的物理引擎也是PhysX。且PhysX的开源性很好,自研引擎也可以完整的集成其功能,所以该载具模拟系统几乎所有游戏引擎通用。因为其泛用性和影响力,其原理和使用方法都是有着很强的普适性。即使不使用PhysX开发游戏载具,也可以参考PhysX的思路,来获取音频所需的参数,以满足开发需求。
因为UE的界面更加直观和简洁,且有高完成度的演示DEMO可以直接使用,所以我们先从UE入手,熟悉物理引擎中和载具音频相关的基础参数。
二、UE和Unity集成physX载具模块参数调整详解
我们打开UE的载具蓝图,选择载具移动。然后可以在细节窗口看到和载具相关的设置。之前的Blog中我曾经简单介绍过部分界面的属性。这次我们来解析的更加详细些。
车辆配置

启用的弹簧偏移模式:该设置只影响车辆行驶和碰撞时的抖动表现,启用后将使用较新的模拟方式。
翻转为制动:自动翻转操作,倒车时向后将视为油门,向前将视为刹车。一般在硬核车辆驾驶模拟的项目中不勾选该选项,倒车与否取决与玩家的挡位设置。普通只用四方向键操作的项目都可以勾选该选项。
质量:车辆模拟模块中车底盘的重量,越重车量的物理状态就越难以改变。会影响车辆的加速、减速转向等性能。该项目属于物理引擎中刚体的基础属性。
车轮设置:数组的数量代表车辆车轮的个数。主要影响车辆的外观、驾驶手感以及性能消耗。
此部分和音频相关度不是很大,属于车辆的基础物理属性设置,音频职能一般也不需要调整此部分。
回避:是否使用RVO系统。
RVO全称Reciprocal Velocity Obstacles也就是障碍物规避算法。车辆在靠近障碍物时是否会有自动规避动作。和音频关系不大,该大项及其子项略过。

组件tick
设置UE中的组件tick功能是否开启,以及tick的频率。和音频关系不大,主要影响游戏同步性。

车辆输入
影响玩家操作手感的数值。

闲置制动输入:当玩家松开油门也不踩刹车时是否默认玩家采取了制动行为,以及制动的强度。值越大,玩家松开油门后车辆降速越快。
停止阈值:车速小于该值时默认执行刹车,以免游戏中出现玩家停不了车,车辆会以极低速度缓慢滑行的现象。
错误方向阈值:如果玩家当前操作和车辆行驶状态相反,且程度大于该值后,将视为刹车。
机械设置:对车辆运行手感以及音频表现影响最大的模块。内容也较多,不全部截图了。
扭矩曲线

横轴为发动机转速,纵轴为发动机扭矩。可以近理解为发动机在不同转速下输出的动力的大小。扭矩的设置会影响车辆的加速性能,同时也会影响车辆的最大车速,这里是车辆调教时容易出错的点,因为很多人会认为发动机转速越快,输出的动力越大,这个理解是错误的。真实车辆发动机的扭矩曲线一般为抛物线(自吸型发动机)或者梯形线(涡轮增压型发动机)。但是如果游戏中的车辆并不是十分写实,也可以不完全按照真实车辆的扭矩设置,可以根据需要适当改变曲线的样式。该选项卡的设置会影响车辆的加速度和车辆的最大速度,直接影响这两种情况下的声音表现,非常重要。更多关于汽车扭矩的相关知识请参考前文提到的blog内容。
引擎设置

最高RPM:发动机的最大转速,达到设定值后就不会继续提升。关于该参数需要注意的是,这个值仅仅影响引擎输出的RPM值,并不会限定车辆的总体性能。真正限制RPM变化范围的的东西是扭矩曲线,所以扭矩曲线和最大RPM值需要结合在一起,扭矩曲线右方最低点对应的RPM值应保持和RPM最大值相同。如果不同的话,当最大RPM值设置小于扭矩曲线可以实际达到的最大RPM时,那么车辆会在达到最大RPM值以后保持RPM不变的情况下继续加速。这其实是很不正常的,因为真实车辆在发动机转速达到仪表片最大值的时候会断油,停止对发动机的油料供给,以保护车辆自身的机械结构。如果最大RPM值设置大于扭矩曲线可以实际达到的最大RPM时,那么车辆运行时发动机的转速将一直维持在中低区间,不会接近最大值。导致发动机听起来很平,没有什么力度。
MOI:发动机转动的惯性量,惯性越大状态越难以改变,加速的时候提速就越慢,空油门时发动机自然降速的速度也会越慢。
阻尼率完全油门:可以简单的理解为油门最大情况下发动机自身的阻力大小。这个值越大,发动机可以对外提供的动力越小。主要影响手感和速度表现,在音频方面会对车辆的加速度和最大速度形成较轻微的影响,在车辆行驶表现正常的情况下,音频同学可以忽略该参数。
阻尼率零油门离合已结合:可以简单的理解为零油门状态下,车辆总体的阻力大小,影响离合结合情况下,车辆空油门自然减速的速度。会对车辆减速状态下的视觉和音频表现形成影响。
阻尼率零油门离合未结合:可以简单的理解为零油门状态下,发动机自身阻力大小,影响空档时发动机自然减速的速度。主要影响空油门情况下的发动机音频表现。更多关于离合结合的相关知识可以参考前文提到的Blog的离合器章节。
差速器设置
差速器是车辆在转弯时控制车轮的转速及角度的一种机械结构,因为车辆转向时,内圈车轮与外圈车轮转向的角度与自身速度都有所差异,所以需要差速器来控制不同的车轮在转向时的运行状态,以及对于每个车轮施加的力量的大小。该选项对音频的影响较小,主要影响车辆转弯的操作手感。音频同学一般不太需要去调节它。

变速箱设置
车辆参数设置错误的又一重灾区,因为该部分对视觉体验的影响并不是很大,如果没有配套的音频表现的话,换档操作在纯视觉的表现上甚至是一个负加成,因为换档的瞬间发动机的动力是断开的,车辆在视觉上会出现“顿一下”的表现,所以如果以纯视觉参考的话,很可能会无限压缩换档时间,甚至直接将把挡位切换抹掉。这样的结果就是,车辆在音频的表现上不会换档,而实际生活中,所有以内燃机为动力的车都离不开换档这个操作,以内燃机为动力且不换档的车,非常稀少,就算有一般也会是油电混合驱动等特殊类型。比如 Koenigsegg Regera。所以大部分的车都无法逃开挡位切换这一要素,挡位切换的流畅与否直接决定了游戏中的一款车是否拟真。如果你不换档,那么玩家大概率会觉得这车像电动玩具车。

自动变速:可以简单的理解车是自动挡还是手动挡。硬核驾驶模拟的游戏可以根据车辆种类自行切换。普通四方向键操作的游戏可以无脑勾选。因为一般也不会给玩家做升降挡和离合器的操作键位。
齿轮切换时间:车辆完成一次换档所需要的时间。该值需要和Rev内档位切换时间的设置相统一。
齿轮自动盒体延迟:如果是自动挡的车,该参数决定两次换档之间的间隔。完成一次换档之后,在该设定时间内,不会触发第二次换档。
最终比:该值越大,车辆跑的越慢,和扭矩曲线共同决定车辆的最大车速。该值主要是用来对车辆的速度表现进行整体缩放。不同游戏里对车辆最大速度的限制是不一样的,但是不同游戏里的车的发动机最大转速并不会有太大差距。此时我们就需要使用最终比来调整车速使其符合我们游戏内对载具最大速度的需求。
齿比:某挡位下的齿轮比,决定该挡位下车辆可以达到的最大车速。不同挡位需要设置不同的齿轮比,以模拟真实车辆中不同档位下发动机转速和车速之间的对应关系。具体公式我就不说了(大家都不喜欢看公式对吧),有几个关键点大家明白就可以。1、比值越小,当前档位可以达到的最大车速越快。所以通常是高挡位比低挡位的比值小。2、不同挡位间齿比的差距决定了换挡时发动机转速的变化幅度,需要合理设置。齿轮比差距越大,换挡时发动机转速的变化就越大。如果差距过大可能会导致车辆无法完成升档,或者升了挡以后车速反而下降的情况。如果差距设置过小,那么车辆会频繁的触发换挡动作。失去拟真感。
上齿比:如果是自动挡的车辆,当发动机当前转速>=最大RPM值*上齿比时,则自动升挡。
下齿比:如果是自动挡的车辆,当发动机当前转速<=最大RPM值*下齿比时,则自动降挡。
ReverseGearRatio:倒挡齿轮比,通常为负值且和挡位1的齿轮比相同或相近。一般不设置为正值,会导致无法倒车。
NeutralGearRatio:空档齿比,一般只有上齿比。自动挡的空档情况下,发动机转速达到多少以后开始闭合离合。一般设置为10%左右。真实车辆在起步时,并不会第一时间提升档位到1挡,而是会在空挡将发动机转速进行一定提升以后,才会提升档位至1挡。这是因为真实的内燃机在低转速时输出的扭矩是很低的,不利于车辆的起步。
离合器强度:决定车速和发动机转速之间关联的强度。值越大车速和发动机转速之间互相影响的敏感度越高。
转向曲线
上下齿比的设置需要和齿比结合,不然会出现不会升降挡,或者升挡升不上去等情况。正确的齿比与上下齿比的关系是:
发动机达到上齿比升挡后,新的发动机转速与最大RPM的比值,处于下一挡位的上下齿比之间。且理论上接近下齿比,但是和下齿比间又有一点距离。通常这种情况发动机的升降挡表现一般都比较写实。如果希望自己的车比较类似NFS21的效果,可以将各挡位之间齿比的差距设置的较小,然后上齿比和下齿比之间的差距也小一些,这样车辆在加速过程中发动机转速就会在较高区间内反复变化。而如果想要模拟略微早期版本的NFS,车辆加速过程中可以听到明显的强劲加速过程。那就将各挡位之间的齿比差距拉大,上下齿比之间也有比较大的间距,这样就可以让发动机在每个挡位的变化区间增大。
转向配置
控制调整车辆的转向能力。

该曲线影响车辆的转向性能主要用来区分不同车辆转向能力的不同。纵轴为转向能力,横轴为车速。通常会设置成缓慢下降的曲线,车速越快越难转弯嘛,很合乎常理。
至此载具移动蓝图内的所有参数介绍完毕,发动机相关的主要参数都在这里,然后我们看一下车轮模拟部分的相关参数。


以上分别是Unity中Wheel Collider组件的界面和UE中轮胎蓝图的设置界面。我们来了解一下其中相同的部分。


(如果表格中部分选项在你的Unity版本中不可见,可以尝试使用API直接调用。)
UE中的疲劳选项卡和Wheel Collider组件中的Forward Friction、Sideways Friction都是用来设置轮胎摩擦的相关参数,但是二者含义不一样,分别对应PhysX中不同的API,Unity的设置主要设置轮胎不同方向的摩擦力曲线,我们知道静态摩擦力是比动态摩擦力更大的,这部分设置就用来模拟该现象。Forward Friction是汽车行驶方向的摩擦力,Sideways Friction是轮胎的侧向摩擦力,虽然看起来是独立的数值。但是其实这是一个曲线设置,其效果类似于UE中的扭矩曲线和转向曲线,只不过其表示方式不一样。Unity中没有提供直观的图形界面,而是通过填入曲线关键节点的值来完成曲线的设置,该设置选项转化成图像后的效果是这样的:

UE中可见的几个选项则是设置不同受力情况下滑动产生的幅度和临界值。
关于轮胎的参数音频职能同学其实不需要太过深入的了解其参数调节方法,我们只需要知道有这些设置,明白其大概功能,同时知道其中几个关键参数的取值范围即可,如轮胎摩擦力强度和悬挂行程范围。我们可以使用这两个参数来分别控制轮胎摩擦声和悬挂抖动声。也可以尝试读取其中一些更加复杂的参数来制作更加细致的声音变化。
截止这里,UE和Unity中提供的可视化的编辑项目已经介绍完了。我们发现虽然他们都使用PhysX,但是他们提供的可编辑选项并不完全相同。那么PhysX中是否还有UE和Unity都没有暴露的可使用参数呢?
三、PhysX可调用参数汇总
关于这个问题,英文不错的同学建议直接翻阅PhysX的用户手册:https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/Vehicles.html#introduction 或者直接浏览PhysX的源码。对于英文不太好的同学,我们可以通过以下表格简单快速的了解PhysX中所有的可编辑参数。






自此我们大概明白了PhysX载具模块各项参数的意义,以及调整这些参数会对游戏内的载具,以及载具发出的声音造成什么影响。那么还需要解决一个问题:我们应当如何使用物理引擎输出的这些参数呢?
四、physX输出的参数及其使用方法
此处对于参数的使用以UE+Wwise+rev2为例。
发动机相关参数的读取与使用
UE可以通过蓝图节点直接读取的参数有以下几个:

发动机的当前转速。单位:转/秒
发动机最大转速。单位:转/秒
当前车速。单位km/h
是否使用自动挡
当前挡位
目标档位
Throttle:油门,可以模拟不同油门大小下发动机的声音变化。
Gain:发动机音量,可以控制总体发动机音量的大小。
RPM:发动机的转速,用来控制声音随着发动机转速而改变。
Gear:档位,配合车辆的换档操作。
Velocity:车辆的速度,用来控制声音随着车辆速度发声改变。
Enable Shifting:离合器状态,手动挡的情况下用来模拟空档状态,自动挡状态下决定发动机转速超过上下齿比后是否触发换档声音。
考个驾照,考完就可以理解档位、车速、发动机转速之间到底是啥关系了。
没驾照的话,找个硬核赛车模拟游戏,玩熟练手动挡,然后一边跑,一边盯着游戏里的仪表盘看,就可以明白发动机转速,车速和档位之间的关系。
车辆轮胎摩擦声:我们可以输出车辆轮胎相关的参数,用以得到当轮胎和地面的摩擦情况,用来控制轮胎和地面摩擦的音效,漂移音效也可以使用该参数控制。
车辆悬挂声音:可以输出车辆悬挂拉伸和压缩状态的值,供音频引擎触发和控制车辆悬挂以及车身抖动的声音。可以实时响应游戏中车辆的抖动状态,模拟较为拟真的车辆抖动声音。
车辆刹车声音:可以输出车辆刹车状态的判定,以及刹车状态下的当前车速和轮胎摩擦力大小,用来控制刹车声的触发及调制。
车辆倾斜状态:可以输出防倾杆的状态参数来反馈车辆的倾斜状态,并使声音匹配车辆倾斜状态的效果。
车辆挡位发生变化的接口:虽然REV会根据自身读取到的目标档位和离合参数自动控制换档声音的触发,不需要使用该接口。但是该接口依然有其用途,可以结合RPM参数后用来触发泄压阀等和档位相关的其他声音。
我们先看其中和发动机相关的参数。
REV需求的参数为以下六个:
我们可以看到部分参数是重合的。发动机转速,车速,档位。其中发动机转速,车速这两个可以直接进行线性关联。也就是说RTPC的图像直接拉成直线就可以。音频引擎内可以进行的调整并不多,主要看这两个参数的读数变化过程是否拟真,这直接决定了声音的变化是否合理。那么这怎么变才是合理且拟真的呢?这个问题我们在之前变速箱设置段落已经介绍了,如果还有朋友不是很明白这几个参数之间的关系。此处给诸位提供两个方法或许可以有助于理解帮大家理解:
然后REV会需求油门参数,这个参数略微麻烦,如果游戏可以提供不同的油门大小让玩家操作,比如玩家使用手柄摇杆控制油门大小。那么油门也可以线性关联。如果游戏不提供可控油门大小。默认玩家按下前进就是满油门,松开前进就是空油门的话。则需要给油门添加额外的控制,以使车辆有更好的音效表现。因为没人会在开车的时候,始终把油门踩到底,完全没有中间态。所以该参数需要和游戏中实际控制车辆油门的按键模块相结合。
再然后是档位参数,UE内可以直接读取两种档位参数,一种是当前档位,一种是目标档位。这两者的区别是,在换挡的过程中是否会读取到空挡的值。当前档位会记录换挡过程中从当前档位到空挡再到目标档位的完整过程,而目标档位则是直接反馈换挡完成后的档位。具体使用哪一种需要根据项目的需求来制定,驾驶模拟的话肯定需要读取当前档位。自动驾驶的话,则需要考虑游戏的程序是如何控制自动挡车辆的离合的。如果有完整的离合开闭模拟机制,则可以读取当前档位,否则请考虑目标档位。因为如果离合全程闭合,且读取当前档位的话,会导致在每次换档的时候都会同时触发降档和升档的声音。而读取目标档位则不会有这个问题。
Rev的Enable Shifting参数对应离合器。当该参数读数为1时,车辆换挡会自动触发换挡声音。如果该参数读数为0则不会。如果是硬核驾驶模拟,那肯定有单独的离合器设置,玩家可以控制物理模拟中的离合器强度,直接关联该设置即可。如果是简化的自动挡车辆,因为没有单独的离合器,建议和Throttle参数绑定,踩油门就闭离合,刹车或者不踩油门则断开离合。效果相对会好一些。
其他物理参数的读取与使用
除了以上可以通过蓝图直接获取的参数以外,我们知道physX其实还有一些参数可以帮助我们丰富车辆的表现,我们可以尝试输出以下接口的参数来帮助我们制作更加丰富的车辆声音:
结语
因为笔者的代码水准比较差,之前的验证DEMO的相关功能都是使用蓝图节点来制作的,且验证工程中的音频素材也并未仔细打磨,仅仅为了验证功能,随便找到一个声音就丢进去了。如果我们可以灵活运用physX的所有接口和参数,相信一定可以制作出更高水准的车辆音效。
另外,如果有项目不使用physX作为其物理引擎,也不必担心,我们之前讨论的相关理念和参数设置也依然具有借鉴意义。可以尝试从其他的物理引擎获取类似参数来完成声音的制作。

徐巍
资深音效设计师
网易互娱
立志成为全品类音频制作人,曾参与制作过电影、电视、动画、球幕影院、沉浸式互动场馆等音频设计与制作,现在开始搞游戏了。