提示、技巧和入门
音频是为 Web 上的游戏和虚拟现实体验添加重要主题和沉浸感的基本方式。添加音频并不难,还能为用户带来美妙的体验。Freesound 之类的资源可以让你更轻松地找到 Creative Commons 音效和音乐,从而帮助你积累相关经验。
我最近创建了一个轻松的 VR 体验,它利用 3D 空间音频来制作通过程序生成的音乐。本文涵盖了我在创建该音频时学到的一些东西。
XR锦鲤花园
一个美丽的 VR 花园,伴随着宁静的音乐。用耳机聆听以获得完整效果。
在网络播放音频最根本的办法就是通过HTML<audio>
元素。这能带来很多好处,例如能够在音频流入时播放。所以当你有很长的背景音乐曲目或环境声音循环时,它很适合你。
提示 1. 不要使用 MP3 来循环播放音频
这是播放一些循环背景声音的 HTML 代码:
<audio loop preload id="bgsound">
<source src="assets/ambient/loop.ogg" type="audio/ogg" />
<source src="assets/ambient/loop.mp3" type="audio/mpeg" />
</audio>
注意,音频元素接受多个 来自不同源的元素,例如<picture>
。MP3 具有相当好的压缩性能并且支持广泛,那为什么我们不能只使用 MP3 呢?
MP3 不应该用于循环音频,因为标题信息经常被误读为几毫秒没有声音。这对于 MP3 播放器来说还好,当播放下一首歌曲时,静音部分无法识别,但如果你循环播放,就会产生一些环境噪音,那么几毫秒的无声对听众来说非常刺耳。
OGG 格式也非常好,没有这个问题,但 Apple 设备不行。所以在这种情况下我们会返回使用 MP3。这虽然会产生更糟的效果,但也不失为一种办法。
使用 WAV 的替代方案虽不会有静音问题,但文件大小可能会大 10 倍!!使其成为一种不适合需要快速启动的 Web 格式。
Tip 2. 不要使用自动播放的音频;让用户打开音频。
不要使用自动播放音频,这可能看起来违反常规,因为如果我们向游戏添加音频,我们都希望默认打开音频。
从用户的角度来看,人们对他们是否想要自动播放音频感到非常困惑:
Jo 在 Twitter 上进行的一项民意调查,询问场景应该如何处理音频
最重要的是,某些浏览器(例如 Chrome)将完全阻止音频自动播放,直到用户事件触发音频播放为止。使用阻止自动播放音频的浏览器的最佳方法是使用利用 HTML、CSS 和一些 JavaScript 创建的音频切换开关:
切换按钮
HTML 是一个复选框和标签:
<input type="checkbox" id="canaudio" />
<label for="canaudio">Toggle Audio</label>
CSS 可用于隐藏标签文本,但如果声音被禁用,则显示音频静音符号,如果正在播放音频,则显示扬声器符号。
#canaudio {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
pointer-events: none;
}
label[for="canaudio"] {
position: fixed;
bottom: 1.5rem;
right: 1.5rem;
background: #0004;
padding: 1.5rem;
border-radius: 50%;
border: 2px solid transparent;
width: 3rem;
height: 3rem;
text-align: center;
font-size: 0;
color: white;
}
#canaudio:focus + label[for="canaudio"] {
border: 2px solid white;
}
label[for="canaudio"]::before {
content: "🔇\FE0E";
font-size: 3rem;
line-height: 3rem;
}
#canaudio:checked + label[for="canaudio"]::before {
content: "🔊\FE0E";
}
然后我们侦听此复选框上的事件以开始播放音频元素:
// Ensure the #canaudio element is not checked as some browsers
// Will remember it's state
window.canaudio.checked = false;
window.canaudio.addEventListener('change', function () {
if (this.checked) {
window.bgsound.play();
// initialise the spatial audio
audioInit();
} else {
window.bgsound.pause();
}
});
提示 3. 添加网络中的空间音频并不像你想象中的那么难
网络长期以来一直通过WebAudio PannerNode支持 3D 音频,并且可以通过 Web Audio API 和定位音频的 panner 节点播放你的声音片段。
这非常有效,但可能达不到游戏开发者或发烧友的期望,但 Google 的一个名为Resonance Audio的库在简洁的 API 中提供了高质量的空间声音。
这就是我在最近的 VR 体验XRGarden 中使用的内容。它会在水面上随机点弹奏钢琴音符,并伴随着涟漪效应。
第一步是添加共振库脚本:
<script src="https://cdn.jsdelivr.net/npm/resonance-audio/build/resonance-audio.min.js"></script>
下一步是创建音频内容来播放,因为 Chrome 不允许在没有音频的情况下创建音频内容,我们必须点击事件,因此,我们将使用取消静音按钮来触发:
let hasInit = false;
function audioInit() {
if (hasInit) return;
hasInit = true;
// Create an AudioContext
const audioContext = new AudioContext();
const resonanceAudioScene = new ResonanceAudio(audioContext);
resonanceAudioScene.output.connect(audioContext.destination);
}
如果你的游戏或体验是在房间内进行的,你可以设置房间的大小和墙壁/地板/天花板的材料,以从每个表面获得准确的混响。具体可以在此处获取可用材料的完整列表:https : //resonance-audio.github.io/resonance-audio/reference/web/Utils.html#.ROOM_MATERIAL_COEFFICIENTS
const roomDimensions = {
width: 3.1,
height: 2.5,
depth: 3.4,
};
const roomMaterials = {
left: 'brick-bare',
right: 'curtain-heavy',
front: 'marble',
back: 'glass-thin',
// Room floor
down: 'grass',
// Room ceiling
up: 'transparent',
};
resonanceAudioScene.setRoomProperties(roomDimensions, roomMaterials);
你还需要将听者位置与摄像机位置同步,以便根据用户的视角,判断声音来自正确的位置。
此代码示例适用于流行的 WebGL 库THREE.js,我们计算出相机方向,并使用它来设置 listenerOrientation,然后我们从相机位置设置 listenerPosition。
const tempForwardVector = new Vector3();
const tempUpVector = new Vector3();
function onRender() {
tempForwardVector.set(0, 0, -1);
tempForwardVector.applyQuaternion(camera.quaternion);
tempUpVector.set(0, 1, 0);
tempUpVector.applyQuaternion(camera.quaternion);
resonanceAudioScene.setListenerOrientation(
tempForwardVector.x,
tempForwardVector.y,
tempForwardVector.z,
tempUpVector.x,
tempUpVector.y,
tempUpVector.z
);
resonanceAudioScene.setListenerPosition(
camera.position.x,
camera.position.y,
camera.position.z
);
};
每次渲染帧时都需要调用它,以保持听者位置和方向与相机位置同步。
要从某个位置播放声音,你首先需要加载它:
const audioElement = document.createElement("audio");
audioElement.src = filename;
const audioElementSource = audioContext.createMediaElementSource(
audioElement
);
const source = resonanceAudioScene.createSource();
audioElementSource.connect(source.input);
当你准备好播放时, 你可以设置位置并开始播放:
source.setPosition(position.x, position.y, position.z);
audioElement.play();
这是我在演示中用于处理位置音频的代码,我创建了一个小类来处理所有不同音符的播放,这可使代码保持整洁:
AdaRoseCannon/xrgarden
通过在 GitHub 上创建帐户为 AdaRoseCannon/xrgarden 开发做出贡献。
我希望这可以帮助你通过音频打造引人入胜的网络体验。对于我的 VR 场景,我同时使用了通用背景音频和位置音频。另一种选择是让我所有的环境声音也都在空间上定位。我可以把鸟放在天空中,昆虫在头顶飞来飞去,从用户下方泼水,这将是改善体验的好方法。
原文作者 Ada Rose Cannon
原文链接 https://medium.com/samsung-internet-dev/audio-on-the-web-for-games-and-vr-efcd523a3d58