3D 场景很多时候是需要一些音效、背景音乐的。
那 Three.js 里如何播放音频呢?
用 Audio 相关的 api:

我们来试一下:
npx create-vite audio-api

进入项目,安装依赖:
npm install
npm install --save three
npm install --save-dev @types/three
改下 src/main.js
import './style.css';
import * as THREE from 'three';
import {
OrbitControls
} from 'three/addons/controls/OrbitControls.js';
const scene = new THREE.Scene();
const directionLight = new THREE.DirectionalLight(0xffffff, 2);
directionLight.position.set(500, 400, 300);
scene.add(directionLight);
const ambientLight = new THREE.AmbientLight();
scene.add(ambientLight);
const width = window.innerWidth;
const height = window.innerHeight;
const helper = new THREE.AxesHelper(500);
scene.add(helper);
const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 10000);
camera.position.set(500, 600, 800);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height)
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
document.body.append(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
创建 Scene、Light、Camera、Renderer。
改下 style.css
body {
margin: 0;
}
先跑下:
npm run dev


啥也没有。
我们加入音频:
把这个音频下载下来:

放到 public 目录下:

然后用 AudioLoader 加载之后,用 Audio 来播放:

const listener = new THREE.AudioListener();
const audio = new THREE.Audio( listener );
const loader = new THREE.AudioLoader();
loader.load('./superman.mp3', function ( buffer ) {
audio.setBuffer( buffer );
audio.play();
});
这时候音乐并没有播放,devtools 打印了一条警告:

音频必须在用户交互之后才能播放。
我们这样写:

const loader = new THREE.AudioLoader();
loader.load('./superman.mp3', function ( buffer ) {
audio.setBuffer( buffer );
});
document.body.addEventListener('click', () => {
audio.play();
})
你点一下屏幕就好了,等音频加载完就会播放。 jaudio
audio 有很多属性方法:

document.body.addEventListener('click', () => {
audio.setLoop(true);
audio.setVolume(0.5);
audio.playbackRate = 2;
if(audio.isPlaying) {
audio.pause();
} else {
audio.play();
}
})
setLoop 设置循环播放、seetVolume 调节音量、playbackRate 调整播放速率。
isPlaying 判断播放状态,然后 pause、play 分别是暂停播放。
试下效果:
然后我们可以用 gui 来做下可视化调节,这样可以感受下不同属性对音频的影响:

改了属性后要暂停播放才会生效:

const gui = new GUI();
const obj = {
volume: 1,
loop: true,
playbackRate: 1,
offset: 0,
detune: 0,
play() {
audio.play();
},
pause() {
audio.pause();
}
}
gui.add(obj, 'volume', 0, 1).onChange(value => {
audio.setVolume(value);
});
gui.add(obj, 'playbackRate', [0.5, 1, 2]).onChange(value => {
audio.playbackRate = value;
audio.pause();
audio.play();
});
gui.add(obj, 'loop').onChange(value => {
audio.setLoop(value);
audio.pause();
audio.play();
});
gui.add(obj, 'offset', 0, 150).onChange(value => {
audio.offset = value;
audio.pause();
audio.play();
});
gui.add(obj, 'detune', 0, 1000).onChange(value => {
audio.detune = value;
audio.pause();
audio.play();
});
gui.add(obj, 'play');
gui.add(obj, 'pause');
试下效果:
比如调整 offset:

再调解下播放速率 playbackRate:

调节下音高:

案例代码上传了小册仓库。
总结
这节我们学了 Three.js 如何播放音频。
主要是通过 AudioLoader 加载音频,之后用 Audio 来播放,通过 setBuffer 设置音频数据。
通过 volume、playbackRate、offset、detune 等来调节音频效果。
后面需要用到音频的地方,都可以通过 Audio 来实现。