SpatialAudio
模块提供了一些和空间音频相关的服务,特别是:
在幕后,它:
它是一个游戏侧的 SDK 组件,包括了 Wwise 声音引擎的一部分,如以下流图所示。
SpatialAudio
功能和定义可以在 SDK/include/AK/SpatialAudio/Common/ 中找到。 它的主要功能是在名字空间 AK::SpatialAudio
内提供的。以下是概述:
AK::SpatialAudio::RegisterEmitter
以及 AK::SpatialAudio::UnregisterEmitter
:通知 SpatialAudio 在其余 API 中所使用的发声体游戏对象有哪些AK::SpatialAudio::SetEmitterPosition
以及 AK::SpatialAudio::SetEmitterAuxSendValues
:针对在 SpatialAudio 中注册的发声体,使用这些功能,而不是它们在 AK::SoundEngine
中的对应( AK::SoundEngine::SetPosition
和 AK::SoundEngine::SetGameObjectAuxSendValues
)。AK::SpatialAudio::AddImageSource
以及 AK::SpatialAudio::RemoveImageSource
:用于直接控制 Wwise Reflect 声像源。请参见以下的‘使用“原始”声像源’。AK::SpatialAudio::AddGeometrySet
以及 AK::SpatialAudio::RemoveGeometrySet
:让 SpatialAudio 基于几何空间计算声像源,一遍之后发送给 Wwise Reflect 实例。AK::SpatialAudio::AddRoom
/AK::SpatialAudio::RemoveRoom
,AK::SpatialAudio::AddPortal
/AK::SpatialAudio::RemovePortal
,AK::SpatialAudio::SetGameObjectInRoom
:创建房间和门户,并让 AK::SpatialAudio
知晓哪个房间中有发声体。
|
Note: 您可以将所有对 AK::SoundEngine::SetPosition 和 AK::SoundEngine::SetGameObjectAuxSendValues 的调用替换为 AK::SpatialAudio 的调用。如果对象没有为调用通过 RegisterEmitter 注册到 AK::SpatialAudio,那么这些调用将直接转发到 AK::SoundEngine。 |
如以上所说,空间音频可以用两种不同(但互补)的方式使用,来制作动态早期反射:通过使用 Geometry API,或者直接向 Wwise Reflect 提供原始声像源。这一点在以下的两个小节中有描述。
请参阅 为虚拟现实创建令人信服的混响博客来查看关于几何空间驱动的 ER 的介绍。
使用 AK::SpatialAudio::Init()
来初始化 SpatialAudio。
针对每个应该支持动态ER的发声体,在将相应的游戏对象注册到声音引擎之后,调用 AK::SpatialAudio::RegisterEmitter()。使用
AkEmitterSettings 来确定反射计算的参数。
reflectAuxBusID:承载所需的
Wwise Reflect 插件的 Auxiliary Bus ID。SpatialAudio 会建立一条到该总线的辅助发送连接,但会连接到一条总线的指定实例,该实例和发声体关联到同一个游戏对象。这意味着不同的发声体会发送到辅助总线的不同实例,进而到插件的不同实例。这一点很关键,因为各个发声体的早期反射组都是独特的。这在以下的 'Wwise project setup(Wwise 工程设置)' 中的 Voice Graph 截图中有展示。reflectionsAuxBusGain:辅助总线上的发送电平。
reflectionsOrder:决定计算反射的顺序。碰到一个表面所导致的反射叫做一阶反射。二阶反射是声音到达听者前碰到两个表面所产生的,以此类推。注意!随着阶数增加,产生的反射数目也会成指数级增长。
reflectionMaxPathLength:启发式算法,用来停止反射计算。它的设置值不应超过发声体播放声音的
Max Distance(最大距离)。 针对这些发声体,使用 AK::SpatialAudio::SetEmitterPosition
和 AK::SpatialAudio::SetEmitterAuxSendValues,而不是声音引擎的功能。
使用 AK::SpatialAudio::AddGeometrySet
和 AK::SpatialAudio::RemoveGeometrySet
将相关几何空间推送到 SpatialAudio。 针对每个传递到 AK::SpatialAudio::AddGeometrySet
的反射器,您需要确定一个 Wwise 工程中所定义的 Acoustic Texture ShareSet(生学纹理共享集)。请参阅 AkTriangle::textureID
. 这些 Acoustic Textures 可以被视为材质的反射属性,计算得出的早期反射上会应用滤波,该反射属性会对滤波产生影响。您需要理解总线结构设计的以下这些方面,才能更有效地在您的 Wwise 工程中管理动态环境效果器
辅助总线设计 一般来说,不同的辅助总线是用来表示不同环境的,而这些总线可能承载着不同的 ShareSets,这些 ShareSets 模拟着环境的混响特征。当使用动态早期反射时,比如由 Wwise Reflect 在 SpatialAudio
下处理的那些,后期混响可能还会使用辅助总线上的混响来设计。但是,您可能会想要禁用这些混响的ER部分(如果有 ER 部分的话),因为这部分是应由 Wwise Reflect 处理的。
另一方面, Wwise Reflect 应该和用于后期混响的辅助总线平行运作。下图展示了典型的总线结构,其中 EarlyReflections 总线下的三条辅助总线每条都包含一个 Wwise Reflect 的 ShareSet。您会注意到,在这个设计中,我们只用到了少量 ShareSets 来生成早期反射。这是由于在运行时,这个效果的“空间属性”是由游戏的几何空间来驱动的。我们只在这里使用不同的 ShareSets ,因为我们希望玩家(听者)发出的声音与其他对象发出的声音有不同的衰减曲线。
总线实例 ER 总线(挂接 Wwise Reflect)存在于很多的实例中,实例的数目和想要实现早期反射的发声体数目相当。做到这一点的方式是通过使用 Spatial Audio API 来注册这些发声体,并将其发送到这条总线,如前文所述。为了让这个小戏法能正常工作,您需要为这条总线启用 Positioning 复选框,如下图所示。通过这么做,ER 总线的各种实例所生成的信号将被恰当地混音到下游下一条混音总线的单一实例中。这个单一实例对应监听这个发声体的游戏对象(通过 AK::SoundEngine::SetListeners
设置),这个对象一般是对应玩家(或镜头)的最终听者。
|
Warning: 虽然 ER 总线必须要启用定位才能保证它的所有发声体-实例能融合到听者的总线中,但定位类型必须设置为 2D 而不是 3D,以便避免 Wwise 的“双重 3D 定位”。请参阅 Wwise Reflect 的文档,了解更多详情。 |
发送至后期混响的早期反射 而且,由于游戏对象(发声体)会向用于处理后期混响的辅助总线发送,因此会在 ER 总线和后期混响总线间建立起连接。这一般来说是可取的,因为生成的 ER 之后会用于后期混响的着色和“加浓”为了能做到这一点,您需要保证在 ER 总线上启用Use game-defined auxiliary sends(使用游戏定义的辅助发送)复选框、之后,您可以使用下方的音量滑块,在您想要向后期混响发送的早期反射和直达声的量之间取得平衡。
下图是之前所讲到内容的实时演示。
使用声学纹理 对每个反射三角,游戏都会传递材质 ID。这些材质能以 Acoustic Textures(声学纹理)的形式在 Wwise 工程中编辑,位于 Virtual Acoustics ShareSets 中。在这里您可以定义每种材质的吸声特性。
虽然 Wwise Reflect 可以使用 AK::SoundEngine::SendPluginCustomGameData
直接由游戏控制,但 AK::SpatialAudio
能方便地跟踪记录各个发声体和为声像源打包,从而让使用变得更简单。此外,您可以使用表面反射器(可能在同一个目标总线/插件上)来对“原始”声像源混做混音和匹配。
为每个声像源调用 AddImageSource 。针对总线 ID 以及游戏对象 ID (请注意该游戏对象 ID 也可能是听者,或者主听者)。请参阅 AkReflectImageSource
了解更多有关如何描述声像源的详情。
声像源可能由游戏引擎提供给 Reflect,这些游戏引擎已经通过光线投射,或通过它们自己的声像源算法实现了这一功能。
请参阅上面的 Wwise 工程设置 查看 Geometry API;使用表面反射器来模拟早期反射 ——它也是一样。 您也可以参阅 Wwise Help 中的 Wwise Reflect 文档,查看 FPS 声音上 Reflect 的示例设计。
Room and Portal(房间和门户)服务提供了抽象来实现具有位置(和朝向)的房间,它在后台利用了 3D 总线功能。一般来说,不同的辅助总线是用来表示不同环境的,而这些总线可能承载着不同的 ShareSets,这些 ShareSets 模拟着环境的混响特征。 “Room”就像各种环境一样,并且也要使用辅助总线在 Wwise 工程中建模:Room 中的声音在辅助总线中混音,而这个下混音一般会进入混响,代表房间效果(后期混响)。但是,Room 和标准的环境不同之处在于 Room 与特定游戏对象关联,而不是与听者隐式关联。因此 Room 的游戏对象既是(房间内发声体的)听者,也是(房间混响的)发声体。这让 Room,也就是房间混响的输出,能像其他 3D 发声体一样被放置在 3D 世界中。
此外,AK::SpatialAudio
模块能让您定义 Portal(门户),也就是混响后的房间声进入其它房间时穿过的开口。
AK::SpatialAudio
模块管理着 Room 和 Portal 的游戏对象,以及 Room 内与发声体的关联。Portal 位于游戏设置的位置。另一方面,游戏在处理 Room 时只设置朝向。Room 的位置由 AK::SpatialAudio
维护,当听者在 Room 中时它被设置为等同于听者的位置。
请见以上的 Wwise 工程设置 部分,查看 Geometry API;使用表面反射器来模拟早期反射 来更好了解空间音频背景下 3D 总线的使用和功能。
此处的 Auxiliary Bus(辅助总线)设计与在传统环境建模中的情况没有本质区别。唯一的区别就是它应变为 3D,方法是(在 Positioning 选项卡中)启用定位和将 Positioning Type 设置为 3D,如下图所示。
为了当听者在 Room 中时能让 Room 的混响包络住它,您必须指定一个衰减 ShareSet,并在距离零设置一个散布为 100 的 Spread 曲线。
|
Caution: 很重要的一点就是要理解,在 3D 辅助总线上设置的衰减设置和 3D 声像摆位会在 Room Portal 游戏对象和听者之间生效。在 Room 内的发声体和 3D 辅助总线间应用的衰减是在声音/Actor-Mixer 结构上定义的,这些结构在 Room 内的发声体上播放。 |
在以下示例中使用的 ShareSet 叫做“Portal”,因为它是根据各个 Room 的 Portal 的行为设计的:随着听者远离 Portal,Portal 就变成了一个点声源。在距离变为零时,听者完全穿过 Portal,进入到 Room 内部。正如之前提过,当听者在房间内时,Room 对象会跟随着它,出现这样的情况时,曲线总在距离为零的这点取值。
以下截图显示了一个发声体——无线电——正在向 Auxiliary Bus Mezzanine2 发送。该环境已通过 AK::SpatialAudio
模块注册为 Room,您也能看见有另一个游戏对象被创建出来,它既不是 Radio 也不是听者。
The game needs to register Rooms and Portals using AK::SpatialAudio::AddRoom
and AK::SpatialAudio::AddPortal
. 之后,它会使用 AK::SpatialAudio::SetEmitterAuxSendValues
定期更新发声体的发送值。此外,它必须使用 AK::SpatialAudio::SetGameObjectInRoom
来确认任何时刻发声体以及听者处于哪个 Room 中。
当使用房间和门户 API 时,所有后期混响辅助总线都应设为“Positioning Enabled”,并且定位类型为“3D”。这会保证辅助总线在声部图中为门户和有朝向的房间正确地实例化。空间音频为听者所处的房间以及门户(听者不在的房间)使用同样的辅助总线;但是在这两种情境中辅助总线会在不同的游戏对象上实例化。这两种情境中的行为如下;
如果发声体和听者在同一个房间中:
AkRoomParams
中传送给了空间音频。如果该发声体位于与听者相邻的房间中,并且房间和听者有一个或多个门户联系:
AkPortalParams
中传送给了空间音频。