- 游戏开发
- 图形学
【免费下载链接】turbulenz_engine
Turbulenz is a modular 3D and 2D game framework for making HTML5 powered games for browsers, desktops and mobile devices.
导读
本文面向使用 Turbulenz 引擎开发 HTML5 游戏的音频工程师与前端开发者,系统讲解 SoundEffect 与 SoundEffectSlot 对象 的完整 API:如何通过SoundDevice.createEffect创建混响(Reverb)与回声(Echo)效果、每个参数的物理含义与取值范围、如何借助SoundEffectSlot将同一效果复用到多个声源,以及从效果创建到声源挂接的完整调用链路。读完本文,你将能够为游戏环境(走廊、大厅、洞穴、开阔地形)配置可调的实时音频效果,并理解这些效果在当前引擎实现中的平台能力边界。
SoundEffect 对象概览
SoundEffect对象代表一个由一组参数创建出来的音频效果,它可以被关联(attach)到一个效果槽(effect slot)上。效果本身不直接发声,它通过后续的SoundEffectSlot与声源(Source/GlobalSource)的输出链路结合,对经过它的声音进行处理。
根据 SoundDevice API 文档,一个SoundEffect对象只能通过SoundDevice.createEffect()构造,示例如下:
var effect = soundDevice.createEffect({ name : "HallwayReverb01", type : "Reverb", delay : 0.15 });createEffect的公共参数只有两个:
name:要创建的效果名称(字符串);type:要创建的效果类型(字符串)。如果该类型不被支持,createEffect将创建失败并返回null。
当效果创建成功后,它会继承该类型所定义的全部属性(采用传入值,未传入的属性取默认值)。本文档列出的所有属性,均可通过 getter 读取、通过 setter 写入。在 TypeScript 类型声明 中,SoundEffectParameters将全部参数标记为可选,也印证了"未传参数即采用默认值"的行为。
值得注意:在 WebGL 后端的 SoundDevice 实现 中,
createEffect与createEffectSlot的当前实现直接返回null。这意味着效果处理链路依赖底层 OpenAL EFX 渲染器提供,纯 HTML5 音频后端目前不包含效果实现,详见后文"平台能力边界"一节。
通用属性
name
效果的标识名称,可读写。常用于在代码中区分同一场景中创建的不同效果实例。
// Get var name = effect.name; // Set effect.name = "HallwayReverb01";type
效果的类型字符串,只读。在createEffect时由type参数决定,例如"Reverb"、"Echo"。
// Get var type = effect.type;Reverb 混响效果参数详解
混响(Reverb)效果模拟声音在空间中的多次反射与衰减。Turbulenz 的 Reverb 效果参数完整覆盖了早期反射、后期混响、频谱塑造与空气吸收等物理维度。各参数汇总如下,随后逐一展开:
| 参数 | 含义 | 取值范围 | 默认值 | 单位 |
|---|---|---|---|---|
density | 模态密度,控制晚期混响染色 | 0.0 ~ 1.0 | 1.0 | 线性 |
diffusion | 回波密度 | 0.0 ~ 1.0 | 1.0 | 线性乘数 |
gain | 混响主音量 | 0.0 ~ 1.0 | 0.32 | 线性增益 |
gainHF | 高频反射声衰减(低通) | 0.0 ~ 1.0 | 0.89 | 线性增益 |
decayTime | 混响衰减时间 | 0.1 ~ 20.0 | 1.49 | 秒 |
decayHFRatio | 高频衰减时间相对低频之比 | 0.1 ~ 2.0 | 0.83 | 线性乘数 |
reflectionsGain | 早期反射总量(相对gain) | 0.0 ~ 3.16 | 0.05 | 线性增益 |
reflectionsDelay | 直达声到首次反射的延迟 | 0.0 ~ 0.3 | 0.007 | 秒 |
lateReverbGain | 后期混响总量(相对gain) | 0.0 ~ 10.0 | 1.26 | 线性增益 |
lateReverbDelay | 后期混响相对首次反射的开始时间 | 0.0 ~ 0.1 | 0.011 | 秒 |
roomRollOffFactor | 反射声按距离衰减的滚降系数 | 0.0 ~ 10.0 | 0.0 | 线性乘数 |
airAbsorptionGainHF | 传播介质导致的高频距离衰减 | 0.892 ~ 1.0 | 0.994 | 每米线性增益 |
decayHFLimit | 是否自动限制高频衰减时间 | true / false | true | 布尔 |
density—— 模态密度
Reverb Modal Density 控制晚期混响的染色(coloration)。降低该值会给晚期混响增加更多染色感,使尾音听起来更"金属"或更"空洞";趋近 1.0 时染色最少,混响更平滑。
// Get var density = effect.density; // Set effect.density = 0.3;- 范围:
0.0到1.0 - 默认:
1.0
diffusion—— 回波密度
Reverb Diffusion 控制混响衰减过程中的回波密度。默认值 1.0 提供最高密度;降低扩散度会让混响呈现更"颗粒状"(grainy)的特性,这在打击乐声源上尤其明显。若设为 0.0,后期混响听起来会像一连串彼此分离的独立回声。
// Get var diffusion = effect.diffusion; // Set effect.diffusion = 0.3;- 范围:
0.0到1.0 - 默认:
1.0 - 单位:线性乘数值
gain—— 混响主音量
Reverb Gain 是所有反射声(包括早期反射与后期混响)的总音量控制,它设定最终混音中加入的反射与混响的最大量。取值从 1.0(0 dB,最大量)到 0.0(-100 dB,完全没有反射声)。
// Get var gain = effect.gain; // Set effect.gain = 0.4;- 范围:
0.0到1.0 - 默认:
0.32 - 单位:线性增益
gainHF—— 高频反射衰减
Reverb Gain HF 通过在反射声上施加一个全局低通滤波器来衰减高频。取 1.0(0 dB)表示不滤波;取 0.0(-100 dB)表示高频反射声几乎完全消失。它作用于所有送入该混响实例的声源反射声。
// Get var gainHF = effect.gainHF; // Set effect.gainHF = 0.6;- 范围:
0.0到1.0 - 默认:
0.89 - 单位:线性增益
decayTime—— 混响衰减时间
Decay Time 设定混响的衰减时长。0.1 秒通常对应表面吸声极强的小房间;20.0 秒通常对应表面非常"活跃"(反射强)的大空间。
// Get var decayTime = effect.decayTime; // Set effect.decayTime = 1.9;- 范围:
0.1到20.0 - 默认:
1.49 - 单位:秒
decayHFRatio—— 高频衰减时间比
Decay HF Ratio 设定 Decay Time 的频谱特性,即高频衰减时间相对于低频衰减时间的比值:
- 取 1.0 时是中性的:所有频率的衰减时间相等;
- 大于 1.0 时,高频衰减时间更长,你会听到更明亮、高频拖尾更长的混响;
- 小于 1.0 时,高频衰减时间更短,混响听起来更自然(更"闷")。
// Get var decayHFRatio = effect.decayHFRatio; // Set effect.decayHFRatio = 1.9;- 范围:
0.1到2.0 - 默认:
0.83 - 单位:线性乘数值
reflectionsGain—— 早期反射总量
Reflections Gain 控制早期反射(initial reflections)相对gain的总量。gain设定的是反射声总体量(早期反射 + 后期混响),而本属性在此基础上进一步调整早期反射部分:最大值 3.16(+10 dB),最小值 0.0(-100 dB,即完全没有早期反射)。它不影响后续的混响衰减过程。
调音建议(来自原文档):增大早期反射可以模拟更狭小的空间或更近的墙壁,若同时配合减小reflectionsDelay(缩短反射延迟)效果更明显;要模拟开阔或半开阔环境,可以保持早期反射量不变,同时降低lateReverbGain(后期混响量)。
// Get var reflectionsGain = effect.reflectionsGain; // Set effect.reflectionsGain = 2.1;- 范围:
0.0到3.16 - 默认:
0.05 - 单位:线性增益
reflectionsDelay—— 早期反射延迟
Reflections Delay 是从直达声到达听者,到第一次反射声到达之间的时间差(0 到 300 毫秒)。增大或减小该值可以模拟更远或更近的反射面,从而控制听者对房间大小的感知。
// Get var reflectionsDelay = effect.reflectionsDelay; // Set effect.reflectionsDelay = 0.1;- 范围:
0.0到0.3 - 默认:
0.007 - 单位:秒(注意代码中按秒书写,0.3 秒即 300 毫秒)
lateReverbGain—— 后期混响总量
Late Reverb Gain 控制后期混响相对gain的总量,最大值 10.0(+20 dB),最小值 0.0(-100 dB,即完全没有后期混响)。
需要注意:Late Reverb Gain 与 Decay Time 是相互独立的属性。只调整decayTime而不改动lateReverbGain时,后期混响的总强度(振幅平方的平均值)保持不变——混响只是被拉长或压缩,响度并不会随之变化。
// Get var lateReverbGain = effect.lateReverbGain; // Set effect.lateReverbGain = 3;- 范围:
0.0到10.0 - 默认:
1.26 - 单位:线性增益
lateReverbDelay—— 后期混响开始时间
Late Reverb Delay 定义后期混响相对于首次早期反射的起始时间(0 到 100 毫秒)。减小或增大该值可用于模拟更小或更大的房间。
// Get var lateReverbDelay = effect.lateReverbDelay; // Set effect.lateReverbDelay = 0.23;- 范围:
0.0到0.1 - 默认:
0.011 - 单位:秒
roomRollOffFactor—— 反射声距离衰减系数
Room Rolloff Factor 是按"声源-听者"距离来衰减反射声(含反射与混响)的两种手段之一。它的定义方式与 OpenAL 的 Rolloff Factor 相同,但作用于混响声而非直达声。取 1.0 表示距离每翻一倍反射声衰减 6 dB;其他取值相当于对(源听距离 - Reference Distance)施加一个缩放系数。Reference Distance 是 OpenAL 声源参数,定义了距离滚降生效的内边界:声源比该距离更近时,直达声不再随靠近而增强,反射声同理。
默认值为 0.0,因为默认情况下 Effects Extension 的混响效果会为每个声源自动管理反射声电平,以模拟典型房间中反射声随距离的自然滚降。(注意:如果声源属性标志auxiliarySendFilterGainAuto被设为false,则不再自动管理。)你可以把roomRollOffFactor当作自动控制的补充选项,用来夸大或取代默认的自动滚降。
// Get var roomRollOffFactor = effect.roomRollOffFactor; // Set effect.roomRollOffFactor = 0.7;- 范围:
0.0到10.0 - 默认:
0.0 - 单位:线性乘数值
airAbsorptionGainHF—— 空气吸收高频衰减
Air Absorption Gain HF 控制由传播介质(空气)引起的高频随距离衰减,只作用于反射声。你可以用它模拟透过潮湿空气、干燥空气、烟雾等介质传播的声音效果。默认值 0.994(约 -0.05 dB)每米,对应典型的空气湿度、温度等常规条件:
- 降低该值模拟吸收性更强的介质(例如空气中湿度更高);
- 提高该值模拟吸收性更弱的介质(例如干燥的沙漠空气)。
// Get var airAbsorptionGainHF = effect.airAbsorptionGainHF; // Set effect.airAbsorptionGainHF = 0.938;- 范围:
0.892到1.0 - 默认:
0.994 - 单位:每米线性增益
decayHFLimit—— 高频衰减时间自动限制
当该标志为true时,高频衰减时间会自动保持在一个由airAbsorptionGainHF设定值推导出的上限之下。该限制与decayHFRatio的取值无关,也不会改动decayHFRatio的值。开启后,你可以放心增大decayTime而不用担心高频出现不自然的超长衰减,从而维持自然的混响尾音;设为false则不对高频衰减时间做自动限制。
// Get var decayHFLimit = effect.decayHFLimit; // Set effect.decayHFLimit = false;- 范围:
true或false - 默认:
true
Echo 回声效果参数详解
Echo 效果生成输入信号的离散、延迟副本(实例),延迟量与反馈量均可控。它的延迟是"双抽头"(two tap)结构——你可以控制两路独立回声实例之间的相互作用。参数汇总:
| 参数 | 含义 | 取值范围 | 默认值 |
|---|---|---|---|
delay | 原声到第一个"tap"的延迟 | 0.0 ~ 0.207 | 0.1 |
lrdelay | 第一个 tap 到第二个 tap 的延迟 | 0.0 ~ 0.404 | 0.1 |
damping | 每个回声的高频阻尼量 | 0.0 ~ 0.99 | 0.5 |
feedback | 输出反馈回输入的量 | 0.0 ~ 1.0 | 0.5 |
spread | 各回声的声像(pan)程度 | -1.0 ~ 1.0 | -1.0 |
delay—— 首个回声延迟
控制原声与第一个"tap"(回声实例)之间的延迟。此后,Echo Delay 的值还会用于确定"第二个 tap"与下一个"第一个 tap"之间的时间间隔。
// Get var delay = effect.delay; // Set effect.delay = 0.046;- 范围:
0.0到0.207 - 默认:
0.1
lrdelay—— 双 tap 间延迟
控制第一个"tap"与第二个"tap"之间的延迟。此后,Echo LR Delay 的值还会用于确定每个"第一个 tap"与下一个"第二个 tap"之间的时间间隔。
// Get var lrdelay = effect.lrdelay; // Set effect.lrdelay = 0.1337;- 范围:
0.0到0.404 - 默认:
0.1
damping—— 回声高频阻尼
控制施加在每个回声上的高频阻尼量。由于声音会被反复反馈产生后续回声,阻尼会使回声在强度与音色上逐次变柔和——回声一次比一次更闷、更弱。
// Get var damping = effect.damping; // Set effect.damping = 0.78;- 范围:
0.0到0.99 - 默认:
0.5
feedback—— 回声反馈量
控制输出信号反馈回输入的量。用该参数可以制造"级联"(cascading)回声效果:
- 满值(接近 1.0)时,相同的采样会无限重复下去;
- 低于满值时,采样会重复并逐渐衰减。
// Get var feedback = effect.feedback; // Set effect.feedback = 0.235;- 范围:
0.0到1.0 - 默认:
0.5
spread—— 回声声像展开
控制每个回声被"硬声像"(hard panned)的程度:
- 1.0 时,第一个 tap 被硬声像到极左,第二个 tap 硬声像到极右;
- -1.0 时结果相反(默认值即 -1.0);
- 越接近 0.0,声像展开越弱。
// Get var spread = effect.spread; // Set effect.spread = -0.5;- 范围:
-1.0到1.0 - 默认:
-1.0
SoundEffectSlot 对象详解
SoundEffectSlot对象是一个效果的容器。一个槽可以同时关联多个声源,实现"单个效果处理多个声源输出"的复用模式。它通过SoundDevice.createEffectSlot()创建:
var effectSlot = soundDevice.createEffectSlot({ effect : effect, gain : 0.8 });createEffectSlot的参数:
effect:要与槽配合使用的SoundEffect对象,只能在创建槽时设置;gain:应用到槽输出的增益,0.0 表示静音。
如果effect不是有效的SoundEffect对象或参数不正确,createEffectSlot返回null(见 SoundDevice API 文档)。
effect—— 槽内效果(只读)
附加到槽上的效果对象。该值只能在SoundEffectSlot创建时指定,之后不可更改。
// Get var effect = effectSlot.effect;gain—— 槽输出增益
应用于SoundEffectSlot输出的增益,0.0 为静音。可以用它来单独调整"效果湿声"在最终混音中的比例,而无需改动声源本身的音量。
// Get var gain = effectSlot.gain; // Set effectSlot.gain = 0.1;- 范围:
0.0到1.0 - 默认:
1.0 - 单位:线性增益
auxiliarySendAuto—— 自动发送调整
启用或禁用基于声源与听者物理位置的自动发送调整。当应用希望用混响效果模拟听者(或一组声源)周围的环境时,应将该属性保持启用。
// Get var auxiliarySendAuto = effectSlot.auxiliarySendAuto; // Set effectSlot.auxiliarySendAuto = true;- 范围:
true或false - 默认:
true
实战链路:从效果创建到声源挂接
将效果真正作用于声音,需要走完"效果 → 槽 → 声源 Auxiliary Send"的完整链路。以 3D 声源(Source)为例:
// 1. 创建混响效果(未指定的属性取默认值) var effect = soundDevice.createEffect({ name : "HallwayReverb01", type : "Reverb", decayTime : 1.9, gain : 0.4, density : 0.3 }); if (!effect) { // type 不支持或参数错误时返回 null } // 2. 创建效果槽,装载效果 var effectSlot = soundDevice.createEffectSlot({ effect : effect, gain : 0.8 }); // 3. 将效果槽挂接到声源的 Auxiliary Send 输出 var result = source.setAuxiliarySendFilter(0, effectSlot, null); // result === false 表示该声源没有 index 0 这个 Auxiliary Send 输出根据 Source API 文档 与 GlobalSource API 文档,setAuxiliarySendFilter(index, effectSlot, filter)的要点如下:
index:Auxiliary Send 的索引。soundDevice.alcMaxAuxiliarySends给出每个声源最多可用的 Auxiliary Send 数量,例如值为 2 时index可取 0 或 1;effectSlot:要应用的效果槽对象,传null表示关闭该路发送;filter:在送入效果槽之前对声源输出做前置处理的SoundFilter对象(例如低通滤波器,参考 SoundFilter API 文档),传null表示不经过滤波;- 在同一索引上重复设置会替换掉之前的效果槽/滤波器;
- 函数返回
true表示操作成功,返回false表示出错(例如声源不支持该索引)。
对不关心空间定位的音效(UI 提示音、背景音乐等),可以改用GlobalSource,它同样提供setAuxiliarySendFilter,效果槽的用法完全一致。此外还需注意:
- 定期调用
soundDevice.update():SoundDevice 的update方法会轮询正在播放的声源状态并更新数据,文档建议每个渲染帧调用一次(例如通过TurbulenzEngine.setInterval(renderFrame, 1000 / 60)),以保证自动发送调整(auxiliarySendAuto)等基于位置的特性持续生效; - 销毁顺序:在调用
TurbulenzEngine.flush()之前,必须把所有使用过的 Auxiliary Send 与 Direct 输出都置为null(如source.setAuxiliarySendFilter(0, null, null)),否则可能导致声音对象销毁时报错。
平台能力边界
需要明确当前仓库的实现边界。SoundDevice 的官方定位是"使用 OpenAL 提供 3D 声音支持"(见 SoundDevice API 文档 开头),并且暴露了alcEfxVersion、alcMaxAuxiliarySends、extensions等属性——其中alcEfxVersion是 OpenAL 实现对 EFX(Effects Extension)扩展支持的版本字符串,alcMaxAuxiliarySends则是每个声源可用的 Auxiliary Send 上限,这些都直接与 SoundEffect 的可用性相关。
但从当前仓库的 WebGL/HTML5 后端源码看,sounddevice.ts 中createEffect、createEffectSlot、createFilter的实现均为直接返回null;声源的setAuxiliarySendFilter同样返回false(见同文件第 1106-1116 行)。由此可以推断:效果处理(EFX)能力依赖具备 OpenAL 渲染器的原生后端提供,纯 HTML5 音频后端目前不包含 SoundEffect/SoundEffectSlot 的实现。也就是说,在纯浏览器 WebGL 环境下调用createEffect会得到null,开发者应当先检查返回值,或依据运行环境(原生 OpenAL 后端 / HTML5 后端)做能力降级处理。
类型定义速查
若使用 TypeScript 开发,可直接参考 turbulenz.d.ts 中的接口定义:
interface SoundEffectParameters { name : string; type : string; // Echo delay? : number; lrdelay? : number; damping? : number; feedback? : number; spread? : number; // Reverb density? : number; diffusion? : number; gain? : number; gainHF? : number; decayTime? : number; decayHFRatio? : number; reflectionsGain? : number; reflectionsDelay? : number; lateReverbGain? : number; lateReverbDelay? : number; roomRollOffFactor? : number; airAbsorptionGainHF? : number; decayHFLimit? : number; } interface SoundEffectSlotParameters { effect : SoundEffect; gain : number; }该文件同时定义了SoundEffect、SoundEffectSlot的运行时属性接口(name、type、全部 Reverb/Echo 参数以及effect、gain、auxiliarySendAuto),与本文前面各属性一一对应,可作为编写强类型代码时的权威参照。
小结
SoundEffect与SoundEffectSlot构成了 Turbulenz 引擎音频效果系统的一对核心对象:前者负责定义"效果是什么"(13 个 Reverb 参数 + 5 个 Echo 参数,覆盖密度、扩散、增益、衰减、延迟、距离滚降与空气吸收等全部维度),后者负责"效果如何接入混音链路"(可复用于多个声源、可独立调节湿声增益、可基于位置自动调整发送量)。配合SoundDevice.createEffect/createEffectSlot与声源的setAuxiliarySendFilter,即可在支持 OpenAL EFX 的平台上为游戏搭建完整的空间音频效果管线;而在纯 HTML5 后端上,需要依据createEffect返回null的特性做好能力检测与降级。
- 游戏开发
- 图形学
【免费下载链接】turbulenz_engine
Turbulenz is a modular 3D and 2D game framework for making HTML5 powered games for browsers, desktops and mobile devices.
相关推荐
Turbulenz SoundDevice 音频设备 API 详解:基于 OpenAL 的 3D 声音引擎实战指南
Turbulenz SoundDevice 音频设备 API 详解:基于 OpenAL 的 3D 声音引擎实战指南 Turbulenz 引擎的 SoundDev
游戏开发图形学Turbulenz 引擎高层 GPU 粒子系统 API 详解:ParticleManager 与 ParticleArchetype 完全指南
Turbulenz 引擎高层 GPU 粒子系统 API 详解:ParticleManager 与 ParticleArchetype 完全指南 本篇技术指南围绕
游戏开发图形学MoviePy MultiplyVolume 音频音量倍增效果详解:参数、原理与实战
MoviePy MultiplyVolume 音频音量倍增效果详解:参数、原理与实战 导读 MultiplyVolume 是 MoviePy 中用于 统一缩放音
音视频视频处理音频处理
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考