在 Three.js 中允许在场景中添加声音,将声音与 3D 对象关联,实现更丰富的交互体验。
Audio
Three.js 中的Audio对象用于表示音频源,它是一个THREE.Object3D的子类,用于控制音频播放、暂停、是否循环等设置的对象,可以添加到场景中,并与其他 3D 对象关联。它依赖于 Web Audio API,因此需要浏览器支持。
            
            
              js
              
              
            
          
          const audio = new THREE.Audio(listener);实例化构造函数,接收一个必选的音频监听器参数,用于接收和处理音频信号。
属性:
- 
isPlaying:布尔值,表示音频是否正在播放。
- 
hasPlaybackControl:布尔值,表示音频是否具有播放控制权。
- 
playbackRate:浮点数,表示音频播放速度,默认值为 1.0。
- 
offset:浮点数,表示音频播放的起始位置,默认值为 0.0。
- 
duration:浮点数,获取音频的时长,但是不是在 Audio 上,而是使用 buffer 的 duration 属性。
- 
autoplay:布尔值,是否自动播放音频。
- 
context:音频上下文,构造函数中传入 listener 的 AudioContext.。
- 
detune:整数,修改音高,以音分为单位。 +/- 100 为一个半音, +/- 1200 为一个八度。默认值为 0。
- 
gain:AudioGainNode,用于控制音频的音量。
- 
source:Audio 对象的 source,属性属于底层的 Web Audio API。通过 source 可以控制音频的播放、暂停、循环等。
方法:
- 
connect(destination):将音频连接到目标节点。
- 
disconnect(destination):将音频从目标节点断开连接。
- 
getVolume():获取音量。
- 
play():播放音频。
- 
pause():暂停音频。
- 
stop():停止音频。
- 
setLoop(loop):设置音频是否循环播放。
- 
setVolume(volume):设置音量。
- 
setBuffer(buffer):设置音频缓冲区。
- 
onEnded():播放完成后自动调用。
            
            
              js
              
              
            
          
          // 创建一个AudioListener对象
const listener = new THREE.AudioListener();
// 将AudioListener对象添加到相机上
camera.add(listener);
// 创建一个Audio对象,并将AudioListener对象作为参数传入
const sound = new THREE.Audio(listener);
// 创建一个AudioLoader对象
const audioLoader = new THREE.AudioLoader();
// 加载音频文件
audioLoader.load("./audio/song.ogg", (buffer) => {
  // 将加载的音频文件设置为Audio对象的缓冲区
  sound.setBuffer(buffer);
  // 设置Audio对象循环播放
  sound.setLoop(true);
  // 设置Audio对象的音量为0.5
  sound.setVolume(0.5);
  // 播放Audio对象
  sound.play();
});
// 在控制台打印Audio对象
console.log(sound);
// 获取按钮元素
const btn = document.querySelector(".btn");
// 为按钮添加点击事件监听器
btn.addEventListener("click", () => {
  // 如果Audio对象正在播放,则暂停播放
  if (sound.isPlaying) {
    sound.pause();
    // 否则,播放Audio对象
  } else {
    sound.play();
  }
});有时候播放会报警告,这个时候就需要手动触发播放。
The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.
不允许启动音频上下文。用户在页面上做出手势后,必须恢复(或创建)它。
AudioListener
AudioListener是 Threejs 中用来管理 3D 音频的核心类,创建一个音频监听器。需要将AudioListener对象添加到相机上,以便在播放音频时能够正确地处理声音的位置和方向。
            
            
              js
              
              
            
          
          const listener = new THREE.AudioListener();
camera.add(listener);属性:
- 
context:音频上下文,构造函数中传入的 AudioContext 对象。
- 
gain:该属性标时音频系统中的主音量控制器,可以通过它来调节整个场景的音量。
- 
filter:用于处理音频的滤波器。允许对音频信号进行过滤或效果处理。例如:可以用滤波器来创建环绕声效果或调节音质。
方法:
- getInput():获取音频监听器的输入节点。
            
            
              js
              
              
            
          
          const listener = new THREE.AudioListener();
const gainNode = listener.getInput();
gainNode.gain.value = 0.5; //调节整个场景音量到50%- setMasterVolume(volume):设置主音量。范围:0.0 到 1.0。
            
            
              js
              
              
            
          
          listener.setMasterVolume(0.5); //调节整个场景音量到50%- setFilter():设置滤波器。
            
            
              js
              
              
            
          
          //创建一个低通滤波器
const lowPassFilter = listener.context.createBiquadFilter();
lowPassFilter.type = "lowpass";
//低于500Hz的频率会通过,高于500Hz的频率会被衰减
lowPassFilter.frequency.value = 500;
sound.setFilter(lowPassFilter);createBiquadFilter():创建一个滤波器,用于处理音频信号。可以设置滤波器的类型、频率、Q 值等参数。
音频效果是用于处理音频数据的对象,可以对音频进行各种处理,如混响、均衡器等。在 Three.js 中,可以使用ConvolverNode、GainNode、BiquadFilterNode等对象来创建音频效果。
PositionalAudio
PositionalAudio它继承自Audio类,用于创建具有空间定位效果的 3D 音频。会根据音源的位置和方向来计算声音的到达方向,从而实现更逼真的声音效果。
            
            
              js
              
              
            
          
          const sound = new THREE.PositionalAudio(listener);方法:
- 
setRefDistance(distance):用于设置音源在特定距离内保持最大音量的范围。当音源距离监听器超过这个距离时,音量会逐渐减小。
- 
setRolloffFactor(rolloffFactor):用于设置音量随距离变化的速率。默认值为 1,表示音量随距离线性减小。如果设置为 0,则音量不会随距离变化。
- 
setMaxDistance(maxDistance):用于设置音源的最大距离。当音源距离监听器超过这个距离时,音量会变为 0。
- 
getDistanceModel():获取音量随距离变化的模型。
            
            
              js
              
              
            
          
          //创建一个音频监听器
const listener = new THREE.AudioListener();
//将音频监听器添加到相机上
camera.add(listener);
//创建一个位置音频对象
const sound = new THREE.PositionalAudio(listener);
//创建一个音频加载器
const audioLoader = new THREE.AudioLoader();
//加载音频文件
audioLoader.load("./audio/song.ogg", (buffer) => {
  //将音频缓冲区设置为音效的缓冲区
  sound.setBuffer(buffer);
  sound.setRefDistance(1); //设置音效开始衰减的距离
  sound.setLoop(true);
  sound.setVolume(0.5);
  sound.play();
});
//将音效关联到物体上
const sphere = new THREE.Mesh(
  new THREE.SphereGeometry(1),
  new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
scene.add(sphere);
sphere.position.set(15, 0, 0);
sphere.add(sound); //将音效关联到物体上拖动这个球体,可以听到音效的位置发生了变化。
AudioAnalyser
AudioAnalyser是 Three.js 中用于分析音频数据的类,可以获取音频的频谱数据,从而实现音频可视化效果、分析音频的频率和波形数据、与场景元素结合实现音频驱动的动画。
            
            
              js
              
              
            
          
          const listener = new THREE.AudioListener();
camera.add(listener);
const sound = new THREE.PositionalAudio(listener);
const audioLoader = new THREE.AudioLoader();
audioLoader.load("./audio/song.ogg", (buffer) => {
  sound.setBuffer(buffer);
  sound.setLoop(true);
  sound.setVolume(0.5);
  sound.play();
  //创建AudioAnalyser对象,传入sound和FFT大小
  const analyser = new THREE.AudioAnalyser(sound, 32);
  //获取频率数据
  const data = analyser.getFrequencyData();
  console.log(data);
  //获取平均频率
  const averageFrequency = analyser.getAverageFrequency();
  console.log(averageFrequency);
});参数:
- 
audio:音频对象,用于获取音频数据。
- 
fftSize:用于设置 FFT 大小,默认值为 2048。FFT 大小决定了频谱数据的分辨率,较大的 FFT 大小可以提供更详细的频谱数据,但会消耗更多的计算资源。
方法:
- 
getFrequencyData():获取频率数据,返回一个 Uint8Array 数组,每个值表示一个频率段的强度,范围为 0 到 255。用来创建频谱分析、柱状图等可视化效果。
- 
getAverageFrequency():获取平均频率。用于判断整体的音量水平。适用于音频驱动的动画或音量监控。

AudioContext
AudioContext是 Web Audio API 的核心对象,用于创建和管理音频节点,处理音频数据,播放音频等。在 Three.js 中,可以通过AudioListener对象获取AudioContext对象,然后使用AudioContext对象创建音频节点,处理音频数据。
            
            
              js
              
              
            
          
          const listener = new THREE.AudioListener();
camera.add(listener);
const audioContext = listener.context;