目录

空间音频

spatialAudio_flowChart.png

Spatial Audio 模块提供了一些和空间音频相关的服务,特别是:

  • 为已知几何空间的 Reflect 计算声像源;
  • 通过控制 3D 总线对 Room(房间)和 Portal(门户)的声音传播进行建模;
  • 对被阻挡声源绕过几何体边缘的衍射进行建模;
  • 方便地访问 Wwise Reflect 的原始 API。

在幕后,它:

  • 通过管理游戏对象及其属性(位置、辅助发送、声障和声笼)来控制 3D 总线;
  • 控制 Spatial Audio 游戏对象的单点/多点定位和辅助发送;
  • 运行几何声音反射和衍射算法;
  • Multi Editor;

它是一个游戏侧的 SDK 组件,包括了 Wwise 声音引擎的一部分,如以下流图所示。

SpatialAudioFlow
AK::SpatialAudio namespace AK::SoundEngine namespace Wwise Reflect Plug-in SetPosition() SetPosition() SetEmitterAuxSendValues() SetGameObjectAuxSendValues() RegisterEmitter() RegisterGameObj()

Spatial Audio 相关概念

以下段落将简要阐述几个与 Spatial Audio 相关的基本声学概念:

衍射

在声波遇到小型障碍物、大型障碍物边缘或房间开口边缘时,会在其周围发生弯曲,出现衍射现象。这时声音会穿过房间开口(门户),传播到另一侧。也就是说,听者不用站在房间开口正前方也能听到声音。在游戏中,衍射通常十分重要。因为它可以给玩家以提示,告知玩家与发声体之间存在哪些路径。在以下声场图中,平面波从右上方入射,并在传播过程中遇到有限面(图中表示为从中央向外延伸的黑线)。此边缘造成的扰动即称为“衍射”。左侧区域为 View Region(可视区)。在此,平面波直接穿过,不发生任何改变。右上区域为 Reflection Region(反射区)。在此,平面波遇到表面发生反射,并与入射波混合,呈现锯齿状。右下区域为 Shadow Region(阴影区)。在此,衍射发挥主导作用。此图只是一个粗略示意图;在现实中,区域边界处的声场是连续的,而且 View Region 也会出现边缘衍射,只是与入射波本身相比通常可以忽略不计。

diffraction_field_plot.png

我们可以把边缘看作一个点声源,其振幅随距离减小。并且,频率越高,振幅减小得越快。也就是说,我们可以使用低通滤波器准确地对其进行建模。Wwise Spatial Audio 通过两个 API 函数构建衍射模型。如需了解如何利用 Room 和 Portal 构建门户衍射模型,请参阅“房间和门户”的“衍射”部分;如需了解如何利用几何构造构建发声体及早期反射衍射模型,请参阅“使用 Geometry API 模拟衍射”部分。

透射

另一个相关声学现象是障碍物对声音的吸收以及声音对障碍物的透射(即有一部分能量会透过障碍物)。通常,在附近存在房间开口时,透射能量相较于通过衍射传播到听者所在房间的能量可以忽略不计。

房间耦合

在经过足够长时间后,发声体会在所处环境内制造出一个基于声学属性的漫反射场。在游戏中,为了模拟这一情形,通常会利用混响效果器来调节参数,并以此表示与其关联的环境。另外,漫反射场还会穿过房间开口和墙壁,传播到听者所在房间。

声障和声笼(Obstruction and Occlusion)

声障代表了各种各样的声学现象,它涵盖声波遇到障碍物时发生的所有情况。声笼与之相似,只是声音无法绕过障碍物。Wwise 声音引擎允许游戏开发人员为游戏对象设置 Obstruction(声障)和 Occlusion(声笼)值,并将其映射至一系列音量、低通滤波器和高通滤波器曲线。两者的区别是,Obstruction 仅会影响 Actor-Mixer 或总线与其输出总线之间的干声/直达信号,而 Occlusion 会同时影响辅助发送。因此,在发声体和听者位于同一房间时,可利用 Obstruction 更好地模拟障碍物对声音的阻挡作用;在声音透过闭合墙壁时,可利用 Occlusion 更好地模拟声音对障碍物的透射作用。

API 概述

Spatial Audio 功能和定义可以在 SDK/include/AK/SpatialAudio/Common/ 中找到。 它的主要功能是在名字空间 AK::SpatialAudio 内提供的。API 函数分为以下 4 类:

  • 基本函数
  • Room 和 Portal API
  • Geometry API
  • 辅助函数:用于直接访问 Wwise Reflect(原始镜像声源)

AK::SpatialAudio::Init() 外,其他基本函数均用于将游戏对象信息(如发声体和听者及其位置)告知 Spatial Audio,以便使用其他 Spatial Audio 服务。Room 和 Portal API 利用简单的上层几何抽象概念对其他房间内发声体的声音传播进行建模。Geometry API 直接使用三角形来计算镜像声源以结合 Wwise Reflect 模拟动态早期反射,或者计算几何衍射。另外,Spatial Audio 还提供有一些辅助函数,方便直接访问 Wwise Reflect 的原始 API。

基本函数

使用 AK::SpatialAudio::Init() 来初始化 Spatial Audio。

所有游戏对象都要使用 AK::SoundEngine::RegisterGameObj 注册到 Wwise 声音引擎,倘若要用于 Spatial Audio,则还需使用 AK::SpatialAudio::RegisterEmitter 将其作为发声体注册到 AK::SpatialAudio

另外,还要使用 AK::SpatialAudio::RegisterListener 将与之唯一对应的听者注册到 AK::SpatialAudio

Warning.gif
Warning: 目前,Spatial Audio 仅支持一个顶层听者。

若要将发声体和听者所在位置告知 Spatial Audio,请调用 AK::SpatialAudio::SetPosition,而不要调用 AK::SoundEngine 函数 (AK::SoundEngine::SetPosition)。另外,由于它可能会以透明方式设置游戏定义的辅助发送,所以假如想另行设置游戏定义的辅助发送而又不干扰 Spatial Audio 操作,请调用 AK::SpatialAudio::SetEmitterAuxSendValues,而不要调用 AK::SoundEngine::SetGameObjectAuxSendValues

Note.gif
Note: 您可以将所有对 AK::SoundEngine::SetPositionAK::SoundEngine::SetGameObjectAuxSendValues 的调用替换为 AK::SpatialAudio 的调用。如果对象没有为调用通过 AK::SpatialAudio::RegisterEmitter 注册到 Spatial Audio,那么这些调用将直接转发到 AK::SoundEngine
Warning.gif
Warning: Spatial Audio 可以处理计算好的多个 Room 和 Portal 位置。不过,Spatial Audio 发声体或听者只能指定一个位置。因此,假如为游戏对象设置了多个位置,请不要将其作为发声体或听者注册到 Spatial Audio。

使用 Geometry API

Geometry API 方便游戏开发人员将三角形网格发送至 Wwise Spatial Audio,以实现以下两个目的: 1. 模拟声音从发声体传播到听者所在位置的过程中产生的边缘衍射(参见“使用 Geometry API 模拟衍射”部分)。 2. 利用 Wwise Reflect 模拟早期反射(参见“使用 Geometry API 模拟早期反射”部分)。

描述几何构造

游戏的几何构造通过 AK::SpatialAudio::SetGeometry() 传给 Wwise Spatial Audio,并由 AkGeometryParams 结构进行描述。下面简要介绍了相关要点:

  • 顶点 (AkVertex) 在独立于三角形的 AkGeometryParams::Vertices 数组中定义,而三角形数组中的每个三角形都会引用顶点数组中的索引。
  • 每个三角形还会包含 AkAcousticSurface 结构索引,便于定义声学材质、描述字符串和反射器声道掩码。
  • 声学材质与三角形的对应关系由用户决定。比如,用户可选择为每个三角形指定一个表面,也可将一个表面应用于所有三角形。
  • 定义声学表面为可选项。若无需自定义表面的声学属性,则可将三角形设为 AK_INVALID_SURFACE,将 NULL 传给 AkGeometryParams::Surfaces ,并将 AkGeometryParams::NumSurfaces 设为零。

如何为 Spatial Audio 创建三角形网格

一般来说,任何三角形网格都可用于 Wwise Spatial Audio,不过需要注意一些关键考量因素。

  • 网格应尽量简单。声学计算涉及大量射线追踪运算,可能会占用很大一部分资源。最好使用最少数量的三角形来表示场景。
  • 所有三角形都具有双面性。三角形的两个面上都会发生声学反射,因此最好创建没有内部体积的网格。比如,将墙壁创建为平面而不是箱体。
  • 为了创建连续网格,应将重复顶点融为一体。也就是说,两个相连的三角形应引用顶点数组中相同的两个顶点。这对衍射计算来说非常重要,否则声音可能会从网格渗透过去。
  • 所有顶点坐标都采用世界坐标系。
  • 为了设置几何构造而通过多个调用发送至 Spatial Audio 的网格不可引用相同的顶点,因此也不会被视为相连或连续。在这种情况下,将不会为跨越多个网格的边缘生成衍射边缘。
  • 网格不得包含退化三角形。所有三角形的面积都必须大于零。
  • 在结合几何构造使用 Geometric Diffraction(几何衍射)时,注意适用其他规则。请参阅 使用 Geometry API 模拟衍射 了解更多详情。

使用 Geometry API 模拟早期反射

为了计算镜像声源以模拟动态早期反射,Geometry API 会结合 Wwise Reflect 插件使用发声体和听者位置以及构成游戏中简化几何构造的三角形。声音设计师可以直接在 Wwise Reflect 中根据距离和材质调节相应属性,从而控制镜像声源位置的转换。

如需简要了解几何构造驱动的早期反射(简称 ER),请参阅动态早期反射的声源成像法为虚拟现实创造引人入胜的混响这两篇博文。

游戏侧设置

针对每个应该支持动态ER的发声体,在将相应的游戏对象注册到声音引擎之后,调用 AK::SpatialAudio::RegisterEmitter()。使用 AkEmitterSettings 来确定反射计算的参数。

  • AkEmitterSettings::reflectAuxBusID:承载所需的 Wwise Reflect 插件的 Auxiliary Bus ID。Spatial Audio 会建立一条到该总线的辅助发送连接。不过,它会连接至与发声体所对应同一游戏对象关联的总线。这意味着不同的发声体会发送到辅助总线的不同实例,进而到插件的不同实例。这一点很关键,因为各个发声体的早期反射组都是独特的。这在以下的 'Wwise project setup(Wwise 工程设置)' 中的 Voices Graph 截图中有展示。
  • AkEmitterSettings::reflectionsAuxBusGain:Auxiliary Bus(辅助总线)上的发送电平。
  • AkEmitterSettings::reflectionsOrder:要计算的反射阶数。碰到一个表面所导致的反射叫做一阶反射。二阶反射是声音到达听者前碰到两个表面所产生的,以此类推。注意!生成的反射数量随阶数呈指数级增长。
  • AkEmitterSettings::reflectionMaxPathLength:启发式算法,用来停止反射计算。它的设置值不应超过发声体播放声音的 Max Distance(最大距离)。 针对这些发声体,使用 AK::SpatialAudio::SetPositionAK::SpatialAudio::SetEmitterAuxSendValues,而不是声音引擎的功能。 使用 AK::SpatialAudio::SetGeometryAK::SpatialAudio::RemoveGeometry 将相关几何空间推送到 SpatialAudio。有关 Geometry API 的更多详细信息,请参见“使用 Geometry API”部分。 几何构造指派有多个声学表面,可绑定至 Wwise 工程中定义的 Acoustic Texture(声学材质)共享集。请参阅 AkAcousticSurface::textureID。这些 Acoustic Textures 可以被视为材质的反射属性,计算得出的早期反射上会应用滤波,该反射属性会对滤波产生影响。

Wwise 工程设置

您需要理解总线结构设计的以下这些方面,才能更有效地在您的 Wwise 工程中管理动态环境效果器。

辅助总线设计

一般来说,不同的辅助总线是用来表示不同环境的,而这些总线可能承载着不同的 ShareSets,这些 ShareSets 模拟着环境的混响特征。当使用动态早期反射时,比如由 Wwise Reflect 在 Spatial Audio 下处理的那些,后期混响可能还会使用辅助总线上的混响来设计。但是,您可能会想要禁用这些混响的ER部分(如果有 ER 部分的话),因为这部分是应由 Wwise Reflect 处理的。

另一方面, Wwise Reflect 应该和用于后期混响的辅助总线平行运作。下图展示了典型的总线结构,其中 EarlyReflections 总线下的三条辅助总线每条都包含一个 Wwise Reflect 的 ShareSet。您会注意到,在这个设计中,我们只用到了少量 ShareSets 来生成早期反射。这是由于在运行时,这个效果的“空间属性”是由游戏的几何空间来驱动的。我们只在这里使用不同的 ShareSets ,因为我们希望玩家(听者)发出的声音与其他对象发出的声音有不同的衰减曲线。

auxbus_hierarchy.png

总线实例

ER 总线(挂接 Wwise Reflect)存在于很多实例中,实例的数量与要生成早期反射的发声体相当。做到这一点的方式是通过使用 Spatial Audio API 来注册这些发声体,并将其发送到这条总线,如前文所述。为了让这个小戏法能正常工作,您需要为这条总线启用 Positioning 复选框,如下图所示。通过这么做,ER 总线的各种实例所生成的信号将被恰当地混音到下游下一条混音总线的单一实例中。这个单一实例对应监听这个发声体的游戏对象(通过 AK::SoundEngine::SetListeners 设置),这个对象一般是对应玩家(或镜头)的最终听者。

Warning.gif
Warning: 虽然 ER 总线必须启用 Listener Relative Routing(听者相对通路)才能确保将所有发声体实例并入听者对应总线,但是为了避免 Wwise 进行“双重 3D 空间化”,必须将 3D Spatialization(3D 空间化)模式设为 None(无)。同样地,除非希望在 Wwise Reflect 中为镜像声源曲线应用额外衰减,否则不要使用衰减设置。
aux_bus_positioning.png

发送至后期混响的早期反射

另外,由于游戏对象(发声体)会向 Auxiliary Bus 发送早期反射以便处理后期混响,所以也会在 ER 总线和后期混响总线之间建立一条连接。这一般来说是可取的,因为生成的 ER 之后会用于后期混响的着色和“加浓”为了能做到这一点,您需要保证在 ER 总线上启用Use game-defined auxiliary sends(使用游戏定义的辅助发送)复选框、之后,您可以使用下方的音量滑块,在您想要向后期混响发送的早期反射和直达声的量之间取得平衡。

aux_bus_generalsettings.png

下图是之前所讲到内容的实时演示。

runtime_voices_graph.png

使用 Acoustic Texture

对于每个反射三角形,游戏都会传递材质 ID。这些材质能以 Acoustic Textures(声学纹理)的形式在 Wwise 工程中编辑,位于 Virtual Acoustics ShareSets 中。在这里您可以定义每种材质的吸声特性。

acoustic_texture_editing.png

使用 "原始" 声像源

虽然 Wwise Reflect 可以使用 AK::SoundEngine::SendPluginCustomGameData 直接由游戏控制,但 Spatial Audio 能方便地跟踪记录各个发声体和为声像源打包,从而让使用变得更简单。此外,您可以使用表面反射器(可能在同一个目标总线/插件上)来对“原始”声像源混做混音和匹配。

游戏侧设置

为每个声像源调用 AK::SpatialAudio::SetImageSource 。针对总线 ID 以及游戏对象 ID (请注意该游戏对象 ID 也可能是听者,或者主听者)。请参阅 AkReflectImageSource 了解更多有关如何描述声像源的详情。

声像源可能由游戏引擎提供给 Reflect,这些游戏引擎已经通过光线投射,或通过它们自己的声像源算法实现了这一功能。

Wwise 工程设置

请参阅上面的 Wwise 工程设置 查看 使用 Geometry API 模拟早期反射 ——它也是一样。 您也可以参阅 Wwise Help 中的 Wwise Reflect 文档,查看 FPS 声音上 Reflect 的示例设计。

使用房间和门户

Spatial Audio 模块利用简单的上层几何抽象概念(即 Room 和 Portal)对其他房间内发声体的声音传播进行准确建模。对于房间驱动的声音传播,其主要特性为衍射、耦合以及混响的空间化。在 Wwise 中,声音设计师可以利用工具来模拟这些特性,从而完全掌控接下来的音频变换。另外,还可将游戏引擎驱动的基于射线投射的声障限制到听者所在同一房间内的发声体上。这类声障处理高度依赖于游戏引擎,而且通常很消耗性能。

Room 没有尺寸大小,它们通过 Portal 相互连通,并形成由房间和开口组成的网络。其他房间发出的声音可以通过开口传播至听者所在房间。Spatial Audio 会利用此网络来修改干声信号传输距离、显式入射位置和衍射角。衍射角度会映射至声障或内置游戏参数 Diffraction。声音设计师可使用 RTPC 将该参数绑定至相关属性(如音量和低通滤波器)。另外,Spatial Audio 还会将相邻房间的混响置于门户位置,并允许使用 3D 总线将这些混响耦合到听者所在房间的混响中。最后,房间还有朝向属性。也就是说,在房间内,关联混响产生的漫反射场会在传播到听者前发生旋转,最终与游戏的几何构造而非听者头部绑定。

API 概述

对于所有 Spatial Audio 服务,在使用 AK::SpatialAudio::RegisterEmitterAK::SpatialAudio::RegisterListener 注册发声体和听者前,必须先将对应游戏对象注册到声音引擎(参见 AK::SoundEngine::RegisterGameObj)。AkEmitterSettings::roomReverbAuxBusGain 是唯一与 Room 和 Portal 相关的发声体设置,方便按发声体来控制辅助总线的发送电平。

您需要根据地图或关卡的几何构造使用 AK::SpatialAudio::SetRoomAK::SpatialAudio::SetPortal 创建 Room 和 Portal。在运行时,可使用相同 ID 再次调用这些函数,从而更改 Room 和 Portal 相关设置。然后,游戏会针对每个发声体和听者调用 AK::SpatialAudio::SetGameObjectInRoom,进而将两者所在房间告知 Spatial Audio。从 Spatial Audio 的角度来说,Room 并没有固定的位置、形状或尺寸。因此,它们可以是任何形状。不过,为了确定对象所在 Room,游戏引擎需要执行几何包含关系检测。

Warning.gif
Warning:注意,请谨慎设置 Room ID(房间 ID)。它们的取值范围与游戏对象相同。因此,假如某个 ID 已经用于游戏对象,切勿将其重复用作 Room ID。

Audio 会在后台针对每个 Room 将游戏对象注册到 Wwise。该游戏对象不可直接用于 AK::SoundEngine 调用。

AkRoomParams::ReverbAuxBus 是最重要的 Room 设置,可在发声体位于该 Room 内时告知 Spatial Audio 应发送至哪条辅助总线。其他设置将在下文部分探讨(参见“使用 3D 混响”和“透射”部分)。

Portal 代表两个 Room 之间的开口。与 Room 相反,Portal 对应有位置和尺寸。因此,Spatial Audio 可自行执行几何包含关系检测。Portal 尺寸由 Portal 设置 AkPortalParams::Extent 给定。Spatial Audio 会使用宽度和高度(X 和 Y)计算衍射和散布,同时使用深度 (Z) 定义 Spatial Audio 在哪个区域内精确操控辅助发送电平、Room 对象方位及 Spread(用于 3D Spatialization),进而在两个相连 Room 之间应用平滑过渡。有关更多详细信息,请参见“使用 3D 混响”和“关于游戏对象”部分。另外,还可使用 AkPortalParams::bEnabled 设置将 Portal 设为启用(打开)或禁用(关闭)状态。

在针对给定发声体使用 Spatial Audio 服务时,请使用 AK::SpatialAudio::SetPosition,而不要使用 AK::SoundEngine::SetPosition。另外,请不要将 AK::SoundEngine::SetMultiplePositions 用于 Spatial Audio 发声体,因为 Spatial Audio 内部依赖于自己的多点定位。不过,对于与 Spatial Audio 无关的游戏对象,尽可使用 AK::SoundEngine::SetMultiplePositionsAK::SoundEngine::SetMultiplePositions 应被视为底层定位功能:在使用时,需要自行管理相应环境。同样地,也不要将 AK::SoundEngine::SetGameObjectAuxSendValues 用于 Spatial Audio 发声体。不过,对于 Room 内的 Spatial Audio 发声体,可以使用 AK::SpatialAudio::SetEmitterAuxSendValues。有关更多详细信息,请参见“ spatial_audio_roomsportals_complexroomreverb”部分。

另外,请不要将 AK::SoundEngine::SetObjectObstructionAndOcclusionAK::SoundEngine::SetMultipleObstructionAndOcclusion 用于 Spatial Audio 发声体。在发声体位于其他 Room 时,Spatial Audio 会利用更为精确的衍射和透射概念来管理声障/声笼。房间内部声障需要使用 AK::SpatialAudio::SetEmitterObstructionAndOcclusionAK::SpatialAudio::SetPortalObstructionAndOcclusion 来设置。有关声障、声笼以及如何将其用于 Spatial Audio Room 和 Portal 的更多详细信息,请参见“为其他房间的声音传播建模”和“在游戏端对同一房间内的声音传播进行建模”部分。

Integration Demo 示例(SDK/samples/IntegrationDemo 中)设有演示页面,并包含有关如何使用 API 的说明。请转至 Demo Positioning > Spatial Audio: Portals(演示定位 > Spatial Audio: 门户)。

声障和声笼以及门户的透射和衍射

在 Wwise Spatial Audio 环境下,完全利用抽象概念 Room 和 Portal 来管理其他房间的声音传播。若 Room 未设打开的 Portal,则使用 Wwise Occlusion 构建透射模型;若 Room 设有打开的 Portal 且存在至少一条到听者所在房间的传播路径,则使用 Obstruction 或 Diffraction 内置游戏参数。对于房间内部的声障,系统会请求游戏根据几何构造或射线投射服务以及规定的细节层次自行应用合适的算法。不过,需要使用 AK::SpatialAudio::SetEmitterObstructionAndOcclusionAK::SpatialAudio::SetPortalObstructionAndOcclusion,以免与 Spatial Audio 衍射争夺资源。有关如何将房间内部声障用于 Spatial Audio 的更多详细信息,请参见“在游戏端对同一房间内的声音传播进行建模”部分。

如需回顾相关声学概念,请参见“Spatial Audio 相关概念”部分。

声音传播特性概要

下表简要列出了 Spatial Audio Room 和 Portal 的特性,并根据声学现象进行了分组,同时说明了与之对应的 Spatial Audio 属性以及声音设计师如何将其用于工程。

Acoustic Phenomenon Spatial Audio Sound Design in Wwise
Diffraction of direct path
  • Obstruction or Diffraction built-in parameter
  • Modified game object (virtual) position
  • Volume, filtering, or any property on Actor-Mixer
  • 3D panning, Distance attenuation
Diffuse field (reverb)
  • Send to room's auxiliary bus
  • Constant power transitions
Reverb, bus volume and game-defined send offset on Actor-Mixer
Room coupling: reverb spatialization and diffraction of adjacent room's diffuse field
  • Obstruction or Diffraction built-in parameter
  • Room object positioning and spread
  • Send to listener's room's auxiliary bus
  • Volume, filtering, or any property on Bus
  • 3D panning of busses, reverb, bus volume and game-defined send offset of Auxiliary Bus to other busses
Transmission (only when no active portal) Occlusion Volume or filtering on Actor-Mixer

使用 3D 混响

Spatial Audio Room 和 Portal 所用的 Auxiliary Bus 设计与传统的环境建模并无本质区别。它要求为每个 Room 指派一条 Auxiliary Bus,并针对其启用声音设计师所选混响效果器。无论听者是在 Room 内部还是外部,使用的都是同一条总线。唯一的区别是需要在 Positioning(定位)选项卡中启用 Listener Relative Routing,并将 3D Spatialization 设为 Position + Orientation(位置 + 朝向)或 Position(位置),以便将其设为 3D 模式(如下图所示)。如此一来,Spatial Audio 便可在 Portal 位置对相邻 Room 的混响进行空间化处理,进而作用于 Room 内的游戏对象定位和 Spread(散布)。

set_positioning_to_3D.png

Room 的基准朝向在房间设置(AkRoomParams::UpAkRoomParams::Front)中定义,并保持不变。对应游戏对象的朝向与 Room 的朝向保持一致。在听者位于 Room 内时,Spatial Audio 会将总线的 Spread 设为 100(360 度)。借助 3D 定位,可根据听者和 Room 的相对朝向旋转混响输出,并将其摆位至父总线。这是因为 Auxiliary Bus 与 Room 内的游戏对象绑定,而父总线又与听者绑定。以下截图显示了一个发声体——无线电——正在向 Auxiliary Bus Mezzanine2 发送。从下图可以看出,针对该房间(Ak_RV_Mezzanine)创建了独立的游戏对象 。该对象既不是 Radio(无线电),也不是听者 (PlayerCameraManager_0)。

voices_graph.png

假如混响中内嵌有空间化早期反射模式(该模式直接存在于 Wwise RoomVerb 的 ER 部分,并间接存在于 Wwise Convolution Reverb 中使用的多声道 IR 录音中),则其将与 Room 绑定,而不会随听者转向。这样做是为了适当营造沉浸感。换句话说,最好使用“旋转特性稳定”的配置。Ambisonics 配置相对于旋转具有不变性,所以更合适。标准配置(4.0、5.1 等)则不太合适。在使用标准配置时,最好选用没有中置声道的配置,并为各条辅助总线应用完全相同的配置,同时将 Focus(聚焦)设为 100。在这种情况下,假设 4.0 混响跟随 Room 朝向北方,那么听者在面朝北方时听到的混响效果会跟直接指派给扬声器时一样。听者在面朝正东、正西或正南时则会听到原始混响,但声道会互换。最后,听者在面朝其他方向时会听到每个声道的原始混响被混入一对输出声道。

在听者远离房间对应 Portal 时,Spatial Audio 会根据 Portal 的尺寸来缩小散布范围,随着距离的延长逐渐将混响输出收缩为点声源。在听者位于 Portal 中间时,Spread 设为 50(180 度)。在穿过房间后,Spread 进一步增大。此时,房间开口始终朝向最近的 Portal。

相邻 Room 的混响应被视为 Portal 位置的声源。您可以在 Auxiliary Bus 对应 Positioning 选项卡中使用 Attenuation(衰减)共享集来决定相对于听者距离的行为。若针对此总线选择 Enable Game-Defined Sends(启用游戏定义的发送),则允许进一步发送至听者所在 Room 的混响(见下图)。您可以使用 Game-Defined Send Offset(游戏定义的发送偏置)来调节发送至听者所在房间混响的散布量,并使用 Game-Defined Attenuation(游戏定义的衰减)来调节距离。在以下示例中使用的 ShareSet 叫做“Portal”,因为它是根据各个 Room 的 Portal 的行为设计的:随着听者远离 Portal,Portal 就变成了一个点声源。在距离变为零时,听者完全穿过 Portal,进入到 Room 内部。

portal_shareset.png
Warning.gif
Warning:注意,为了允许 Spatial Audio 根据 Portal 的几何构造来修改 Spread,请勿在 Auxiliary Bus 的衰减设置中包含 Spread 曲线。倘若使用 Spread 曲线,则将改写 Spatial Audio 计算得出的值。

在 Room 内部,Spatial Audio 会将 Room 游戏对象位置保持在听者所在位置,因此所有衰减曲线都将在距离 0 处取值。

关于游戏对象

Spatial Audio Room 和 Portal 的工作原理是操控 Wwise 声音引擎收到的游戏对象(游戏注册的发声体和 Spatial Audio 注册的 Room 游戏对象)的位置及其他固有属性(如游戏定义的发送、声障和声笼)。

发声体

在完成 Spatial Audio 的初始化设置 DiffractionFlags_CalcEmitterVirtualPosition 后,将修改听者相邻 Room 内发声体的位置,使其与听者之间呈衍射角(如适用)。在以下 3D Game Object Profiler(3D 游戏对象性能分析器)截图中,听者 (Listener L) 位于 Portal 右侧,实际发声体 (Emitter E) 位于左下方且无朝向矢量。因此,Spatial Audio 将发声体重新定位到了左上方,使视位置看上去就像从该角落切入一样,并始终符合传播距离的衰减规律。听者与 Portal 边缘的阴影区约呈 45 度,所以衍射系数为 27(如两条线段的交点处所标)。

objects_position.png

在有多个 Portal 连通两个 Room 时,Spatial Audio 会将多个位置指派给发声体(每个 Portal 指派一个)。这时将使用 MultiPosition_MultiDirection 模式,以免在启用或禁用 Portal 时影响与此同时感知到的其他 Portal 的音量。

Warning.gif
Warning:注意,您无法将多个位置用于 Spatial Audio 发声体。只有 Spatial Audio 可以在内部实现这个功能。

房间和门户

Spatial Audio 会在内部按 Room 将游戏对象逐个注册到 Wwise。

Warning.gif
Warning:该游戏对象不可直接使用。

在听者位于 Room 内时,Room 内的游戏对象将随听者移动。因此,Room 和 Listener 对象之间的距离近似为 0。不过,其朝向与 Room 设置 (AkRoomParams) 中指定的朝向保持一致。有关 3D 总线朝向的论述,请参见“使用 3D 混响”部分。

在听者位于 Room 外时,Room 内的游戏对象将沿用对应 Portal 的位置。确切地说,是设在 Portal 后方与 Portal 正切的听者投影位置,并固定于 Portal 界限之内。您可以通过查看 Room 内的游戏对象来验证这一点(参见上文“发声体”部分的 3D Game Object Profiler 截图)。

对于多个 Portal,在 MultiPosition_MultiDirection 模式下,将为 Room 内的游戏对象指派多个位置(情形与发声体相同)。

在 Portal 内部过渡时,会对 Room 内部和 Portal 行为做平滑插值。

为其他房间的声音传播建模

在 Spatial Audio Room 和 Portal 环境下,将利用抽象概念 Room 和 Portal 来管理听者之外其他房间的声音传播。另一 Room 内的发声体会通过多个 Portal 及与这些 Portal 关联的衍射将声音传播到听者;若无衍射路径,则通过声音对房间墙壁的透射来传播。

衍射

对于相邻 Room 内的每个发声体,Spatial Audio 都会计算相连 Portal 最近边缘与 Shadow Boundary(阴影边界)的衍射角。请参见上文“衍射”部分。然后,将此衍射角(最大 180 度)映射为衍射系数 (0 ~ 100%),并提供给 Wwise 用户,以便从两种方式中选一种来设置对应音频变换。用户可为“发声体”游戏对象设置 Obstruction 值,也可设置内置游戏参数 Diffraction 值。Spatial Audio 选用哪种设置取决于初始化时选择的 AkDiffractionFlags。

若要使用 Diffraction 内建参数,则需创建游戏参数,并在对应 Bind to Built-in Parameter(绑定至内建参数)下拉菜单中选择 Diffraction(衍射)。推送至该游戏参数的值的作用域由游戏对象界定,确保与发声体一一对应。然后,可结合使用 RTPC 来控制 Actor-Mixer 的属性。最好选用 Output Bus Volume(输出总线音量)和 Output Bus LPF(输出总线 LPF),来模拟衍射的频率相关行为。Output Bus Volume 和 Output Bus LPF 要优于基准 Volume 和 LPF,因为它们只会应用于直达信号路径,而不会应用于 Room 混响对应的辅助发送。

另外,Spatial Audio 的声音传播模型还包括了 Room 的漫反射能量(作为 Room 对应 Auxiliary Bus 的输出)。Spatial Audio 会同时计算这部分的衍射(湿声衍射)。Spatial Audio 假定漫反射能量沿 Portal 垂直方向从 Room 向外渗透。因此,它会计算相对于 Portal 法向矢量的衍射角。此衍射值可以用在 Wwise 中,方式与发声体的干声路径相同。在使用内置游戏参数时,应结合使用 RTPC 来控制房间对应的辅助总线(通常用于总线的 Output Bus Volume 和 Output Bus LPF)。为了避免影响此混响与听者所在房间混响耦合的辅助发送路径,最好选用总线的 Output Bus Volume 属性,而不要选用 Bus Volume 属性(情形与 Actor-Mixer 相同)。

另外,用户还可使用内置工程全局声障来修改 Spatial Audio 衍射生成的音频。此时,Spatial Audio 会使用计算得出的 Diffraction 值来控制声障。与 Diffraction 内置游戏参数不同,工程全局声障会映射至 Wwise 工程全局曲线。它们可以在 Project Settings(工程设置)中设置。Obstruction Volume、Obstruction LPF 和 Obstruction HPF 可有效作用于 Output Bus Volume、Output Bus LPF 和 Output Bus HPF(如上文所述)。由于声障曲线为全局设置,所以工程全局声障不像 Diffraction 内置游戏参数那样灵活。而另一方面,它们也不需要过多的操控和编辑(使用 RTPC)。另外,不同的 Obstruction 值可应用于游戏对象的各个位置,而内置游戏参数仅可将一个值统一应用于游戏对象的所有位置(在设有多个值时,取最小值)。如上文所述,在 Room 包含不止一个 Portal 时,会使用多个游戏对象位置。

透射

在发声体和听者之间不存在活跃 Portal 传播路径时,Spatial Audio 会改用“发声体”游戏对象的 Occlusion 来构建墙壁透射模型。Occlusion 值从 Room 设置 AkRoomParams::WallOcclusion 获取;最大 Occlusion 值取自听者所在 Room 和发声体所在 Room 之间。Occlusion 会通过 Project Settings 的 Obstruction/Occlusion(声障/声笼)选项卡中定义的工程全局曲线映射至音量、LPF 和 HPF。与 Obstruction 不同,Occlusion 会同时影响发送至辅助总线的信号,而被遮蔽发声体信号对其所在 Room 混响以及耦合混响都有贡献。因此,这些贡献将根据 Occlusion 曲线来缩放和滤波。这样 Occlusion 就可以准确地构建吸收/透射模型。

Note.gif
Note: 由于 Wwise 声音引擎存在相关限制,所以 Spatial Audio 无法同时对衍射和透射建模。不过,墙壁透射的能量相对于打开的门户所衍射的能量而言一般可以忽略不计。

耦合

相邻房间内通过 Portal 渗透到听者所在房间的衍射能量可被视为 Portal 位置的声源,因此也应对听者所在房间产生激励作用。也就是说,应将其发送至听者所在房间对应的 Auxiliary Bus。为此,可针对相邻房间对应的辅助总线勾选 Enable Game-Defined Sends 复选框(如上文所述)。您可以使用 Game-Defined Send Offset 来调节发送至其他房间混响的散布量,并使用 Game-Defined Attenuation 来调节距离。

在游戏端对同一房间内的声音传播进行建模

听者所在房间内的声障可使用 Geometric Diffraction 进行处理(参阅 使用 Geometry API 模拟衍射结合 Room 和 Portal 使用几何构造 API ),但它并不完全依赖 Spatial Audio Room 和 Portal。若不想通过将几何构造发送到 Spatial Audio 来执行声障计算,则须在游戏端处理同一房间内的声障。房间内声障计算中几何构造的表示、方法和规定的细节层次高度依赖于游戏引擎。游戏一般会采用不同复杂程度的射线投射法来实现这一操作。本节提供了一些有关如何结合 Room 和 Portal 在游戏端处理声障的技巧。

不过,借助 Spatial Audio Room 和 Portal,便不用针对每个发声体实施这一操作,而只需考虑听者所在房间内的发声体。这样做有它的好处,因为射线投射法一般会比 Spatial Audio 计算传播路径的算法占用更多资源。顾名思义,发声体和听者之间的房间内部声障作用发生在同一房间。在这种情况下,我们假定障碍物不会完全覆盖听者或发声体,而声音会通过房间内的反射传播到听者所在位置。我们可以通过单纯控制干声/湿声信号路径进行准确建模,而不需要涉及辅助发送。也就是说,Obstruction 机制对此来说最为合适。为此,游戏应调用 AK::SpatialAudio::SetEmitterObstructionAndOcclusion 而非 AK::SoundEngine::SetObjectObstructionAndOcclusion。Spatial Audio 只有通过这种方式才能得知发声体和听者之间存在房间内部声障,进而将此因素融合到计算中,同时确保不会干扰 Obstruction 和 Occlusion 的其他应用(衍射和透射)。

另外,相邻房间的 Portal 应被视为听者所在 Room 内的发声体。因此,游戏还需在听者和所在 Room 的 Portal 之间运行声障算法。然后,还要针对每个 Portal 调用 AK::SpatialAudio::SetPortalObstructionAndOcclusion,以便向听者明确声明房间内部声障。

Warning.gif
Warning:对于注册为 Spatial Audio 发声体的游戏对象,请勿调用 AK::SoundEngine::SetObjectObstructionAndOcclusionAK::SoundEngine::SetMultipleObstructionAndOcclusion

多房间穿透

多个房间之间也会发生声音传播。在搜索传播路径时,会在 SpatialAudio 内部搜索 Room 树。为了避免循环连接,在遇到已经到过的 Room 时,将停止搜索。搜索深度可通过 Spatial Audio 的初始化设置 AkSpatialAudioInitSettings::uMaxSoundPropagationDepth(默认值为 8)来加以限制。

实现复杂房间混响

AK::SoundEngine::SetGameObjectAuxSendValues 会改写游戏对象发送值,因此不可用于 Spatial Audio 发声体。与之相比,AK::SpatialAudio::SetEmitterAuxSendValues 会将值叠加到 Spatial Audio 已经设置好的辅助发送。这在设计相同房间内的复杂混响时可能会非常有用。比如,物体或地形需要应用不同的环境效果。另外,还可将 Room 对应的 AkRoomParams::ReverbAuxBus 保留为空 (AK_INVALID_AUX_ID),仅由游戏通过 AK::SpatialAudio::SetEmitterAuxSendValues 来管理发送总线。

使用 Geometry API 模拟衍射

我们可以使用传给 Wwise Spatial Audio 的几何构造来模拟声音的衍射。如此一来,便可完全替代游戏引擎在声障计算中使用的射线投射法。在发声体和听者之间有物体阻挡时,Spatial Audio 会沿着物体边缘(如有)计算路径,并计算这些边缘周围声波弯曲产生的衍射系数。同时,相应地修改发声体的视入射角,并将衍射值发送给 Wwise,以便控制对声音的最终影响。通常,衍射会造成低通滤波。

下图为 Wwise 中 3D Game Object Viewer(3D 游戏对象查看器)的截图,它显示了薄壁边缘周围的声音衍射情况。

diffraction.png
Warning.gif
Warning: 虽然我们可以使用几何衍射来完全替代游戏引擎在声障计算中使用的射线投射法,但要注意,随着几何构造越来越复杂,占用资源也会逐渐增加。因此,传给 Spatial Audio 的几何构造应尽量简单。另外,为了降低 Geometric Diffraction 的计算复杂度,最好结合运用 Room 和 Portal 抽象概念,这样会更加高效(参见“使用房间和门户”部分)。

几何衍射可用来影响发声体和听者之间的直达声音传播路径。在结合使用 Wwise Reflect 时,还可用来影响早期反射路径。

针对衍射设置几何构造

对于传给 Spatial Audio 的每项几何构造集,都要明确声明是否要将其用于计算衍射路径。为此,可使用 AkGeometryParams::EnableDiffraction 标记。此标记方便生成衍射计算所需的边缘数据,其在直达路径的几何衍射和反射路径的衍射中均有应用。

另外,还要考虑是否允许网格的边界边缘衍射声音。对于给定网格,边界边缘被定义为多重三角网格边界上仅与一个三角形相连的边缘。边缘数量越多,衍射计算的复杂度越大。因此,在网格包含不会衍射声音的边界边缘时,应禁用相应选项。

最后还要注意,指派给声学表面的声学材质不会对衍射产生任何影响,因为边缘材料并不吸收能量。边缘只会造成声波弯曲。

直达路径的几何衍射

如需了解如何使用几何构造来确定直达路径的几何衍射,请参见 Integration Demo 示例中的 Geometric Diffraction 演示(SDK/samples/IntegrationDemo 中)。请转至 Demo Positioning > Spatial Audio: Geometry(演示定位 > Spatial Audio: 几何构造)。

代码端发声体设置

对于每个需要对直达路径进行几何衍射的发声体,都必须有相应的 AkEmitterSettings。确切地说,AkEmitterSettings::diffractionMaxEdgesAkEmitterSettings::diffractionMaxPathsAkEmitterSettings::diffractionMaxPathLength 必须大于零。有关更多详细信息,请参阅相关文档。

Wwise 中的直达路径衍射

通过适当设置性能分析设置和视图选项,可以在 3D Game Object Viewer 中查看衍射设置(见下图)。在此,将针对各条衍射边缘显示计算得出的发声体与听者之间路径的衍射系数。系统会根据初始化 Spatial Audio 时传递的 AkSpatialAudioInitSettings::uDiffractionFlags,通过 Diffraction 这个内置游戏参数和发声体的 Obstruction 值这两者或者其中之一将此衍射系数传给 Wwise。您可以直接在 RTPC 曲线中分析其所用内置游戏参数值,并在 Profiler 的 Obstruction/Occlusion 选项卡中分析 Obstruction。

profiler_settings.png
3dviewer_settings.png

跟 Portal 一样,在发声体位于听者视线之内时,Diffraction 值为 0。在穿过阴影区的过程中,该值不断增大(参见“衍射”部分)。有关阴影区衍射的更多详细信息以及如何使用内置游戏参数 Diffraction 和 Obstruction 的论述,请参见“房间和门户”的“衍射”部分。

直达路径衍射与 Spatial Audio Room 和 Portal 的相互影响

在使用 Spatial Audio Room 和 Portal(参见“使用房间和门户”部分)时,Portal 也会对相邻房间内直达声音的衍射建模。这两个系统互为补充,对于与听者不在同一房间的发声体,确保不会搜索几何构造驱动的衍射路径。Room 和 Portal 比几何构造的计算效率高很多。为了降低计算复杂度,最好结合使用两个系统。

早期反射的几何衍射

如上文所述,早期反射可能会在边缘附近发生衍射。在发声体连通 Wwise Reflect 的情况下,Spatial Audio 支持对这一现象建模。

在解释如何建模之前,我们需要先定义可视区衍射。

在下图中,发声体位于听者视线之内,但听者并不在镜面反射路径上。因此,它在可视区。如“衍射”中所述,可视区也会出现衍射。不过,在 Wwise Spatial Audio 中,无论是 Room 和 Portal 还是直达路径模型的 Geometric Diffraction,都不考虑可视区的衍射,因为其相较于实际直达路径可以忽略不计。然而,对于反射来说,可视区衍射会产生很大影响。若没有衍射,则只有反射区能听到早期反射(纯镜面反射)。一旦听者进入可视区,反射就会不起作用。在启用衍射后,边缘会衍射反射波。这样在进入和离开反射区时虽然有滤波和衰减,但听者仍可感知到反射。

reflection_diffraction_2.png

在反射区中,镜面反射占据主导,没有衍射路径,因此也不会计算衍射值。在反射区和可视区之间的边界处,给定边缘的可视区衍射计算值为 0;在可视区和阴影区之间的边界处,该值为 100。

对于高阶早期反射,同时存在可视区和阴影区衍射。

代码端发声体设置

在代码中,可以像平常一样设置需要发送至 Wwise Reflect 的发声体以及规定的反射阶数。有关更多详细信息,请参见“游戏侧设置”部分。在此,既不需要针对衍射反射专门设置并启用衍射,也不需要为几何构造启用衍射。

Wwise Reflect 中的设置

在 Wwise Reflect 中,受衍射影响的反射将呈现为镜像声源。您可以根据衍射状况使用以下三条曲线来设计衍射对反射的影响:Diffraction Attenuation(衍射衰减)、Diffraction LPF(衍射 LPF)和 Diffraction HPF(衍射 HPF)。有关更多详细信息,请参阅 Wwise Reflect 文档

结合 Room 和 Portal 使用几何构造 API

我们可以结合 Wwise Spatial Audio 中的 Room 和 Portal 使用几何构造 API 来构建反射和衍射模型。为此,可将 Room 和 Portal 网络视为对周围几何构造的上层抽象(或者说细节程度较低)。适当地结合 Room 和 Portal 使用上层几何构造,可以让声学环境的模拟具有一定细节并且高效。

通过 Portal 模拟几何衍射

在发声体与听者不在同一房间时,将按照以下方式来计算几何路径(假设已针对几何衍射正确设置发声体,参见 代码端发声体设置 ):

  • 使用 Room 和 Portal 网络来计算从发声体到听者的声音传播路径。
  • 对于每一条路径,使用几何衍射算法来计算发声体和最靠近发声体的 Portal 之间的路径段(将该 Portal 视为听者)。除非从听者的角度来看发声体位于某个 Portal 正后方,否则只计算一条几何路径(检测到的最短路径)。计算发声体和 Portal 之间的其他路径只会造成虚声源位置重复,因此是不必要的。
  • 在两个 Portal 之间不存在直接视线时,同样使用几何衍射来计算两者之间的路径段。每次在场景中添加/移除几何构造或 Portal 时都会执行这些计算,并会在需要时重复使用。一般情况下,只会使用两个 Portal 之间的最短路径。不过,若听者位于其中一个 Portal 正后方,则会使用多条路径,以此避免在听者从某一 Room 慢慢进入另一 Room 时通过 Portal 听到的声音出现间断。
  • 对于每一条路径,使用几何衍射算法来计算听者和最靠近听者的 Portal 之间的路径段(将该 Portal 视为发声体)。
  • 将以上路径合并成结果路径,并在必要时细分或附加路径。

通过 Portal 模拟反射

即便有多达两个平面与门户开口相交,反射声也可穿过门户。因为 Portal 本身来说就是声学开口,所以不用在三角形几何构造上另建开口,声音也能穿过。如此一来,便大大减少了所需的三角形数量。比如,在采用箱体构建 Room 的几何构造时,会为六个侧面分别使用两个三角形。若用户希望声音能传到箱体外部,只需添加一个与墙壁相交的 Portal (其 Z 轴垂直于墙面)即可。照例来说,游戏会使用 AK::SpatialAudio::SetGameObjectInRoom 来判定游戏对象是在 Room 内部还是外部(参阅 API 概述 )。 即便发声体(已针对反射正确设置发声体,参见 游戏侧设置 )与听者不在同一 Room,只要听者能通过声音传播网络听到声音,就会执行反射模拟。反射的计算方式如下:

  • 在发声体及其所在房间的每个 Portal 之间执行反射计算(将 Portal 视为听者)。
  • 按照 通过 Portal 模拟几何衍射 中所述来计算 Portal 和听者之间的衍射路径,并将其附加到 Portal 和发声体之间的反射路径。
  • 在衍射路径超出 100% 衍射时,不执行反射计算;即便执行了计算,也会将其忽略。

针对特定 Room 标记几何构造

为了限制射线-三角形相交检测和潜在反射表面的搜索范围,现在可将几何构造手动指派给特定的 Room。为此,请将 AkGeometryParams::RoomID 设为特定 Room 的 ID。这样可以告知 Spatial Audio,该 Room 内的几何构造只能通过 Portal 从另一 Room 看到,无法直接看到。因为一项几何构造集只能关联一个 Room ID,所以除非将 AkGeometryParams::RoomID 设为无效,否则 Room 不能包含可在多个 Room 内看到的几何构造。另外,假如几何构造集被关联到了特定 Room ID,那么在该 Room 内便无法再看到未与其明确关联的几何构造。在将几何构造集指派给 Room 后,在模拟该 Room 内的反射和衍射时,Spatial Audio 仅会查找与对应 Room ID 关联的特定几何构造。

参见: