目录

Wwise SDK 2018.1.11
集成详情——3D 位置

在 Wwise 中,可通过将事件发送给游戏注册和定位的对象来播放声音。这些游戏对象称为 发声体 (emitter)。您可以利用 3D 模拟环境下发声体和 听者 (listener) 之间的相对位置,来进一步设置声音的声像摆位和其他属性,进而构建逼真的 3D 环境并为玩家打造身临其境的视听体验。

在 Wwise 中,设计师既可选择手动对输出到玩家所用扬声器的声音实施声像摆位,也可设为由游戏根据对象位置实时定位声音。另外,还可指派一组衰减曲线和设置,并根据距离或角度来修改声音属性(音量、滤波等)。

设置游戏对象的位置

针对需要使用此信息来定位声音的每个游戏对象调用 AK::SoundEngine::SetPosition() 函数。另外,还要针对“听者”游戏对象调用该函数。每当游戏对象的位置改变时,您都需要设置位置。

AkGameObjectID in_GameObjectID, // Game object 的标识
const AkSoundPosition & in_Position // 想要设置的位置
);

第一个参数是游戏对象的 ID。请参阅 集成详情——游戏对象 了解详情。

第二个参数是 AkTransform 结构,其中包含的向量代表游戏对象的位置和朝向。请参阅 X-Y-Z 坐标系统 了解 Wwise 声音引擎中 X、Y 和 Z 轴分别对应什么。

Note: 这意味着,即使您在调用 AK::SoundEngine::RenderAudio() 函数前多次调用 AK::SoundEngine::SetPosition(),也仍将只考虑最后一个值。

跟踪听者的位置

为了模拟发声体位置自动跟随听者位置的行为,必须在每一帧将游戏对象的位置明确设为与听者位置相同的数值。另外,也可发送作用于“听者”游戏对象的事件。

为单个游戏对象设置多个位置

您可以使用方法 AK::SoundEngine::SetMultiplePositions() 为单个游戏对象设置多个 3D 位置,而不可使用方法 AK::SoundEngine::SetPosition(),因为后者只可为单个游戏对象设置一个 3D 位置。

AkGameObjectID in_GameObjectID, ///< 游戏对象标识符。
const AkSoundPosition * in_pPositions, ///< 要应用的位置数组。
AkUInt16 in_NumPositions, ///< 所提供数组中指定的位置数。
MultiPositionType in_eMultiPositionType ///< \ref AK::SoundEngine::MultiPositionType
);
);

应仔细选择 MultiPositionType。您选择的方法将取决于要创建的场景和效果类型。

  • 如果您使用 MultiPositionType_MultiSources 方法,则会将各个声音的音量累加,以此来模拟多个对象同时发出同样的声音。此方法用处很多,在有多个对象发出同样声音的时候特别适用。然而,此方法在各个声音距离太近时可能会出问题。这个问题在于:因为多个声音完全同相播放,所以音量累加的时候容易出现削波失真。
  • 如果您使用 MultiPositionType_MultiDirections 方法,则各个扬声器中播放的音量是各个方向上的最大值。此方法可用于模拟游戏中的许多场景,包括墙洞、面声源和多个对象同时发出同样的声音。然而,如果游戏玩家希望当若干发声对象距离很近时声音变响,则应使用 MultiPositionType_MultiSources 方法添加声音。
  • 方法 MultiPositionType_SingleSource 不得结合 SetMultiplePositions() 一起使用,因为它只考虑一列位置中的第一个。

通过为单个游戏对象创建多个位置,您可以模拟很多音效,包括:

- 面声源

您可以来模拟面声源,方法是选用 MultiPositionType_MultiDirections,并设置合适的 Spread(散布)和基于距离的音量衰减值。在使用此方法时,需要位置增多的时候音量不会累加升高。通过使用这种方法重建面声源,您可以用一个声音获得从多个方向传来的、有逼真衰减的效果。

在下列中,黑点代表声音的初始位置,黑圆圈代表衰减的最小距离和散布,红圆圈代表最大衰减半径:

AreaSound.gif
图:有多个位置的面声源示例

蓝色区域代表游戏中的湖泊。湖泊发出的环境声通过使用有四个位置的声音来模拟。

当听者位于 A 位置时,湖泊的声音应来自所有方向。这可以通过设置适当高的散布值来实现,高散布值可使声音散布,使它们在所有扬声器中播放。

当听者位于 B 位置时,听者超出了最大衰减距离。这意味着在最大衰减距离处,听者要么会听不到湖泊的声音,要么只能听到微弱的声音。由于您用了多个位置来模拟大湖,因此声音总是会从合适的方向传过来。

当听者位于 C 位置时,将从张角很大的扬声器(~180 度)中听到湖声,但听者到湖泊有一定距离,因此声音会发生衰减。在这种情况下,听者仍位于衰减半径内,因此湖声不会发生最大衰减。

使用这项技术,您可以通过重叠多个声音位置来重建任何类型的对象形状。然而请记住,每添加一个新位置,就需要更多的 CPU 来计算音量结果。

- 同一区域中多个对象发出同样的声音。

举例来说,在游戏的某一关中,走廊墙壁上布置了一系列的火炬,将走廊照得透亮。这些火炬完全一样,会播放完全相同的声音。如果您为各个火炬分别设置一个播放事件(假设有 20 个火炬),那么这将极大地增加 CPU 和内存消耗。另外,如果使用流播放声音,则您可能会有多条重复的流,这会增加 I/O 访问次数。

在这种情况下,使用 SetMultiplePositions() 将极大地提高性能。它还可让您用一次操作来轻松控制所有声音,并减少需要注册的游戏对象的数量。

在游戏中创建此场景时,您可以使用以下两种方法之一: MultiPositionType_MultiSources() 还是 MultiPositionType_MultiDirections()

MultiPositionType_MultiSources 通常更准确,不过如果相互距离太近,则可能会出问题。记住,当只播放一个声部来模拟多个声音时,Wwise 会累加不同位置上的音量,从而可能导致音量超过 0 dB。MultiPositionType_MultiDirections() 占用 CPU 更少,只采用最大音量,然后让各个扬声器按此音量来播放。由于 MultiPositionType_MultiDirections() 不会增加音量,因此它可以保证不会有削波失真发生,因此更适用。

尽管一个声音有多个位置,但声音引擎仍只播放一个声部。这意味着当所有声音都超出值域时,只会处理一个虚声部。

- 模拟从豁口传来的声音(声音重定位)

当声音遇到声障或声笼时,那么可能听起来就像从别的方向而不是从声源的实际位置传来。在这些情况下,您可以将声音摆在多个位置,创建出您希望的效果。

举例来说,假设声部的直接传播路径被建筑物遮挡——见下图。那么使用两个替代点 A' 和 A'',而不是使用对象 A 的实际位置,听起来会更加逼真。当这样做的时候,使用 SetObjectObstructionAndOcclusion() ,这样会对所有位置应用同样的声笼和声障参数,或者也可以使用 SetMultipleObstructionAndOcclusion() ,为各个声音位置指定独有的声笼和声障值。

Buildings.gif
图:使用替代位置重新定位声音

此方法还非常适用于模拟已经被摧毁的环境,声音来自于许多随意的位置。在重新定位声音时,使用这个方法更好:MultiPositionType_MultiDirections()

X-Y-Z 坐标系统

Wwise 声音采用左手坐标系。默认值如下所示,不过最主要的是发声体相对于听者朝向系统的位置和朝向:

  • X:指向右侧的向量
  • Y:上方向量
  • Z:前方向量。
PositioningAxis.gif
Wwise 声音引擎中 X、Y 和 Z 轴的方向。

有关集成 3D 位置的示例,请参阅 3D 位置示例

参见