如果各位了解过 Wwise 2023.1 的新增功能,可能会注意到文档中有这么一句话:“对 Aux Send 模型进行的完善”。这个到底是什么意思呢?今天我们就来详细说说。在此,我会简要介绍对 Wwise Spatial Audio 所做的改进,并详述背后的设计理念、个中细节以及深层动机。不过有一点要提醒大家,内容可能会稍微偏技术。本文主要针对至少在 Wwise 中设置过 Room 和 Portal 或创建过 Room 辅助总线的用户。假如您刚开始使用 Spatial Audio,请先从 Audiokinetic Launcher 下载示例工程,并在 Unreal 或 Unity 地图中设置一些 RoomVerb 效果器。这样可能会从本文中获得更多收获。
在 Wwise 2023.1 中,我们对 Spatial Audio 的信号路径做了逐步的改进。无论是在可用性还是灵活性方面,都有不小的提升。在提到信号路径时,这里特指自动创建总线并在总线之间传输信号的通路。Wwise Spatial Audio 位于 Sound Engine 的顶端,其会按照与模拟情形相符的方式传达有关如何处理和渲染音频的指令。总的来说,总线通路结构基于虚拟世界中 "Emitter"、"Listener" 和 "Room" Game Object 的放置位置。
干声/直接路径
- 直接传播到 Listener 所在位置。
- 声音被认为来自不同的方向。
- 可能会在 Portal 两侧或障碍物周围发生衍射。
- 可能会穿透墙壁。
湿声/间接/混响路径
- 通过间接路径传播到 Listener 所在位置。
- 声音会发生散射和漫反射。
- 难以感知准确的方向。
- 在 Room 的墙壁上多次反弹。
Wwise Sound Engine 提供了一个灵活的框架用以在 Game Object 情境下创建声部和总线。Wwise 设计工具的 Voice Graph 中可直观地显示由 Auxiliary Send 或直接输出通路(统称为“通路”)相连的声部和总线。借助 Voice Graph 和 Voice Inspector,我们可以很好地了解 Sound Engine 内发生了什么。
在本文中,我提供了一些相关的背景信息。若想详细了解 Spatial Audio 如何在 Sound Engine 内传送音频,请参阅文档的 Room 和 Portal 信号模型中的传播路径章节。最好在新的标签页中打开网页,以便稍后需要时回过头来查看。
对于 Wwise 2023.1 中对 Aux Send 模型进行的完善,以下是我们的总体设计目标:
- 我们希望能根据声音来自由设定各种渲染参数(包括衰减、衍射和透射曲线)。在现实生活中,声音遵循一套严格的物理法则。不过,在电子游戏中,为了达到特定的创作效果,往往需要对声音进行个性化设置。比如,为了让对白清晰可闻,必须把有些声音的传播距离设定得比物理学限定的远一些。而且,在设计当中,动态范围是有限的。所以,在虚拟世界中,必须把响亮声音的音量衰减设计得比安静声音更平缓。在 Wwise 2022.1 中,的确可以在 Game-Defined Auxiliary Send 上为每个声音定义衰减曲线,并以此来控制发送到 Room 总线链(湿声路径)的信号量。不过,湿声路径的衍射和透射曲线是分开的,并且各不相同。它们必须由所有穿过 Room 的声音共用。这样有些不合理,处理起来也麻烦。所以,必须加以改进。
- 我们既不希望用户设置不必要的多余曲线,也不希望其在设置曲线时不得不做出妥协。有的时候并没有办法为 Room 设计一条适用于其内所有声音的曲线。比如,如果 Room 中既有脚步声又有射击声,无论设置怎样的曲线都无法做到兼顾。
- 我们希望能模拟声音传到 Room 中再传到外面的声学现象。如果走到洞口大声喊叫或者把气球弄爆,会听到声音在洞里回荡然后再传到外面。在 Wwise 2023.1 之前,只有在 Emitter 或 Listener 处在洞穴中时才能听到洞穴混响。
- 我们希望在确保每个 Room 只有 1 条辅助总线和 1 个混响实例的情况下实现以上目标。如果能为每个声部单独创建混响总线和混响实例,操作起来会轻松很多。这样的话,就可以根据 Emitter 的独有特性精确设定每个混响效果器的输出。遗憾的是,这会导致 CPU 用量大幅增加,从成本上来说是无法接受的。
那么,Wwise Spatial Audio 2023.1 对 Aux Send 模型进行的完善都包含哪些改进呢?
对于湿声路径,所有渲染参数(包括估算的衍射和透射损失值)都移到了信号链中第一条 Room 总线的输入端。假定 Room 总线上的效果器是线性的、不随时间变化(混响效果器通常就是如此),那么不管是在总线之前还是之后对声音实施滤波/衰减,结果都是一样的。最终的音频缓冲区完全相同。
衍射和透射造成的滤波/衰减
将渲染参数移到上游 Room 总线的输入端既可实现设计目标 1,还能进一步实现设计目标 2。因为每个声音都有一条与 Room 总线相连的输入通路,所以每个声音都可应用与之对应的渲染参数。非常方便!不再需要 Room 总线上的衰减曲线,同时还减轻了设置曲线的工作难度。
不过,在 Room 总线的输入端应用衍射也有缺点。这样没法再为 Room 的两个输出端设置单独的衍射值。除非是信号链中的最后一个 Room(即 Listener 所在 Room),否则 Room 总线会有两个输出端:一个到 "Listener" Game Object 的直接输出,一个用于链接到另一 Room 的 Auxiliary Send。在输入端应用衍射时,信号会被预先滤波和衰减。与 Listener 总线直接相连和发送到下游 Room 的信号都已经过滤波。与之相比,Wwise 2022.1 中 Room 的衍射只会应用于直接输出。事实上,这意味着相邻 Room 中的声音不能直接对 Listener 所在 Room 产生激励作用。输出已经经过滤波,高频能量被滤掉了。
为了消除这一弊端并实现设计目标 3,我们在 Emitter 和每个相邻 Room 之间添加了一条新的通路。在此之前,Emitter 只会向 Emitter 所在 Room 发送信号,而不会向相邻 Room 发送信号。这条新通路并不是随便添加的,其背后是有一定的物理基础的:它代表直接从 Emitter 传来的声音,会对相邻 Room 产生激励作用,之前并未在 Emitter 所在 Room 中反弹。
由于 Emitter 现在直接对相邻 Room 产生激励作用,如果 Listener 在其中一个相邻 Room 内,就会听到具有完整频谱和正确衍射值的声音。另外,通过向相邻 Room 发送信号还可模拟声音传到 Room 中再传到外面的声学现象(设计目标 3)。比如,如果 Emitter 和 Listener 都在洞口,附近声音就会对洞口产生激励作用。跟往常一样,洞穴混响也是以 3D 形式进行空间化处理的,听起来就像是从洞口发出的一样,同时带有逼真的声像摆位和散布效果。
1. 声音从 Emitter 传播到 Room 中
2. 声音四处反弹,形成漫反射场
3. 漫反射声场通过 Portal 传播回来并被 Listener 听到
Wwise 2023.1 与 Wwise 2022.1 的区别
为了加深理解,我们来对比一下 Wwise 2022.1 和 2023.1 中的 Integration Demo。Integration Demo 是随 Wwise SDK 一起发布的。如果要下载下来并按照描述操作,可转到 Audiokinetic Launcher 的 Samples 页面。下面有个 Portal and Geometry Demo 中的场景。我在两个版本中都精确地重建了这个场景。其中,Listener 所在 Room 被定义为外部对象,其与包含 Emitter 的内部 Room 相邻。两个 Portal 将两个 Room 连通,形成 3 条传播路径:1 条透射路径(穿过墙壁)和 2 条衍射路径(每个 Portal 一条)。
之前:Wwise 2022.1 中的 Portal 和 Geometry
1. 由 Emitter 到 Room
2. 由 Room 到 Listener
Voice Inspector 有两部分:左侧窗格中的 Voice Graph 和右侧的 Contribution List。Voice Graph 从左向右读取。其中每个节点代表一个混合在一起的音频缓冲区。先在节点之间通路的适当位置应用滤波、衰减、声像摆位/空间化处理,最后在 Master Audio Bus 中实施混音。要了解每一步骤发生了什么,可察看右侧的 Contribution List。Contribution List 从下往上读取。它显示了音量和 LPF 值以及它们是如何得出的。在上面的 Voice Inspector 截图中,请注意看两条高亮显示的通路。它们构成了贯穿 Voice Graph 的信号路径。由 Sound SFX 开始,到 Master Audio Bus 结束。这里的“信号路径”是指 Voice Graph 中的一系列节点(声音或总线)。注意不要跟 Game Object 3D Viewer 中看到的传播路径混为一谈。传播路径是 Wwise Spatial Audio 计算出的虚拟世界中的路径。
Wwise Spatial Audio 理解起来比较复杂,关键在于传播路径和信号路径之间的关系。信号路径以传播路径为基础。它由从 Emitter 到 Listener 的最短路径形成的 Room 序列组成。它们之间不可能是一一对应的关系,因为为了实用性和效率必须做出妥协。需要注意的是,我们希望每个 Room 只有一个混响效果器(上文设计目标 4),而且信号路径中不能有反馈回路。
传播路径决定了路径长度以及衍射和透射系数,而这又决定了如何对 Voice Graph 中的通路实施滤波和衰减。传播路径会显示在右侧的 Contribution List 中来表明与之相关的通路。
注意看两条高亮显示的通路:
1) 由 Emitter 到 Room 的通路(黄色)。
- 这条通路代表在 Room 中产生混响并形成漫反射场的声源所注入的能量。
- 右侧的 Voice Inspector 中显示了三条传播路径,与 Game Object 3D Viewer 中的三条路径对应。
- 在此应用距离衰减。因为它是湿声路径的一部分,所以可对声音的 Auxiliary Send volumes 曲线(游戏定义)进行估算。在这里应用距离衰减非常方便。藉此,可为每个声音设置单独的“湿声”衰减曲线[1]。
2) 由 Room 到 Listener 的通路(蓝绿色)。
- 这条通路代表 Room 的漫反射场。能量会直接传播到 Listener 所在位置,大概率会穿过 Portal(有衍射)或穿过墙壁(有透射损失)。
- 同样,右侧的 Voice Inspector 中显示了三条传播路径,与 Game Object 3D Viewer 中的三条路径对应。
- 在 Wwise 2022.1 及较早版本中,衍射和透射损失应用在这条通路上。注意,除非是 Listener 所在 Room,否则 Room 总线有两个输出端。一个直接输出到 Listener,一个链接到下游 Room(由 Room 到 Room 的通路)。之所以在这条通路上应用滤波,是为了在另一输出端将未经滤波的音频传到下游 Room。这也跟将衍射和声障应用于 Emitter 的直接/干声输出而非辅助/湿声输出的方式一致。
- 注意,衍射值与 Game Object 3D Viewer 中路径上显示的小百分比值并不完全一致。这一点虽然不算什么太大的问题,但关乎如何计算湿声路径的衍射。稍后会详细介绍。
现在:Wwise 2023.1 中的 Portal 和 Geometry
1. 由 Emitter 到 Room
2. 由 Room 到 Listener
现在我们再来看看!衍射、透射和距离衰减都应用在了第一条由 Emitter 到 Room 的黄色通路上。通路 2 现在发挥的作用比较有限,它只包含行为音量(通过调节总线滑杆使混音中的 Room 更加响亮或安静来达到创作效果)。
无法再为 Room 总线定义曲线(设计目标 2)。Room 总线上的曲线将被忽略。现在所有曲线都在一个地方,而且可以根据声音自由设定(设计目标 1)!
技术细节:解决音量上的小问题
将透射和衍射移到第一条通路还解决了在声音引擎中混音上的一个小问题。虽然一条通路可能代表多条声音路径,但每条通路只设置了一个 DSP 滤波器。如果传播路径的滤波器值不同(通常就是如此),我们会使用音量加权平均值来获取最终滤波器值。然后,根据混音时的所需滤波器值和实际滤波器值之间的差值应用响度补偿。由此产生令人信服的混音效果,好像每条传播路径都有自己的 DSP 滤波器。我们在 Wwise 2022.1 及较早版本中遇到的问题是,因为将距离衰减应用在了第一条通路上,而将衍射/透射滤波应用在了第二条通路上,所以音量加权平均值实际上是不正确的 – 因为通路之间并不是互通的。明眼的用户可能已经注意到,其混响的音量总会比预期的要大一些。更糟糕的是,在超出距离曲线末端时,混响有时候会突然中断。这些混响音量问题已经得到解决,现在 Wwise 中的混响效果好多了!
关于 Room 总线上衰减曲线的另一问题
在 Wwise 2022.1 中,在 Room 总线上设置曲线还有一点比较麻烦。如果想为自己所在 Room 自定义一条曲线,就不得不做一些变通。要在 Wwise 中为 Room 总线添加自定义衰减,然后对距离-音量曲线做明确的扁平化处理(因为这条曲线是无法禁用的)。否则,会在信号路径上重复应用距离衰减!如果不必考虑 Room 总线上的衰减曲线,操作起来会轻松很多。
新的通路:由 Emitter 到相邻 Room
3. 由 Emitter 到相邻 Room
上面的截图高亮显示了 2023.1 中的新通路(由 Emitter 到相邻 Room)。如上文所述,这条通路模拟的是来自 Emitter 的声能。它会直接对相邻 Room 产生激励作用,之前并未在 Emitter 所在 Room 中反弹。
现在,由不受 Portal 衍射影响的信号链对 Listener 所在 Room 的混响产生激励作用。正如 Contribution List 中所示,虽然还是应用了衍射,但只是策略性的,作用非常有限。有关如何将衍射应用于湿声路径的详细信息,请参阅 Wwise Spatial Audio 文档中的湿声路径衍射章节(Wwise 2023.1 新增功能)。
除此之外,借助这条新的通路还可模拟前面提到的“洞穴开口”效应。效果不错,不妨一试!
当然,我们一直都很在意性能问题,所以不能创建太多混响总线。尤其是在其对最终结果并没有什么显著影响的情况下,更是如此。为此,我们在 AkSpatialAudioInitSettings 中添加了一项新设置来限制每个 Emitter 的 Room Send 数量。若将 uMaxEmitterRoomAuxSends 降为 1,将完全阻止 Emitter 向相邻 Room 发送信号(跟 2022.1 中一样)。不过我们发现,将值设为 2 或 3 就可以很好地兼顾性能和品质,因为玩家一般都会选择热闹的 Room 而很少选择安静的 Room。
如何计算 Emitter 的 Auxiliary Send 值
说到热闹和安静的问题,我想总结一下我们是如何确定 Emitter 的 Room Send 值的。Emitter 和 Room(无论是自身所在 Room 还是相邻 Room)之间的每条通路都有一个 Room Send 增益。该增益显示在 Contribution List 底部,在上面的 2023.1 截图中就可以看到。距离固定的点声源 Emitter 有恒定且有限的能量要分配给自身所在 Room 和相邻 Room。能量要始终保持恒定,不应随位置或 Room 的变化而波动,除非为创作目的使用设计工具中的增益滑杆进行特别的调整。在任何时间点和空间点,发送值的平方相加都是 1。传到相邻 Room 的能量由 Portal 的散布值决定(严格来说是 Portal 相对于 Emitter 的立体角),并与围绕 Emitter 的整个球体成正比。
下图为顶部视角下的 Game Object 3D Viewer 截图。这跟前面所说的 Integration Demo 场景是完全相同的。
传到 Emitter 所在 Room:80%
传到外面:3%
传到外面:17%
就像扇区一样,Emitter 发出的声能被切成小块并分配给自身所在 Room 和相邻 Room。在以上示例中,80% 的能量分给了 Emitter 自身所在 Room。这些能量会传到 Emitter 所在 Room 的混响总线。剩余 20% 分给了相邻的 Room,并传到相邻 Room 的混响总线(注意,此处数字为近似值,只是为了便于演示)。Portal 表面面积与墙壁的比例决定 Room Send 之间的平衡。封闭 Room 中的 Emitter 会将 100% 的能量传到自身所在 Room。同样的,如果 Portal 开口比墙壁多,大部分能量会分给相邻 Room。
Wwise 2023.1 在 Spatial Audio 方面做了很多改进,“对 Aux Send 模型进行的完善”只是其中一部分。各位可以转到 Audiokinetic Launcher 下载下来试试。如果目前还没有制作自己的游戏,不妨先拿 Unreal Demo Game 练练手,或者下载 Wwise Audio Lab 来做各种尝试。
脚注
[1] 如果在 2017 版本中最初引入 Room 和 Portal 时这样做,就只能为每个 Room 定义距离衰减。操作起来很麻烦,现在方便多了。
评论