mcpField
T
threejs-impl-audio

threejs-impl-audio

github.com/impertio-studio開発23134 回インストール30 週間前に更新
リポジトリ

threejs-impl-audio について

Three.js の 3D シーンに音声を実装するためのリファレンススキルです。通常再生、空間音声、ファイル読み込み、周波数解析に加え、ブラウザーでのユーザー操作要件も説明します。

主な機能

  1. 01オーディオリスナーと再生の設定
  2. 02通常音声と 3D 空間音声
  3. 03音声ファイルの読み込みと再生制御
  4. 04ブラウザーの音声操作要件
  5. 05可視化向けの周波数解析

活用シーン

  1. 01BGM や UI 効果音の追加
  2. 02距離に応じたシーン内音声の配置
  3. 03音声周波数データの可視化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/impertio-studio/three.js-claude-skill-package --skill threejs-impl-audio

インストール後、Claude Code で/threejs-impl-audioを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
anti-patterns.md
examples.md
methods.md

詳細

threejs-impl-audio

クイックリファレンス

クラス階層
EventDispatcher
  └── Object3D
        ├── AudioListener    (receiver — attach to camera)
        ├── Audio            (non-positional — background music, UI sounds)
        └── PositionalAudio  (3D spatial — attached to scene objects)

サポートクラス:

  • AudioLoader — オーディオファイルをAudioBufferに読み込みます
  • AudioAnalyser — ビジュアライゼーション用のリアルタイム周波数分析を行います
アーキテクチャの概要
コンポーネント役割取り付け先
AudioListener仮想の耳(Web Audio APIの出力先)カメラ(必須)
Audio非位置依存のサウンド(どこでも同じ音量)任意のObject3Dまたはシーン
PositionalAudio3D空間サウンド(音量は距離に応じて変化)シーン内のMeshまたはObject3D
AudioLoaderオーディオファイルの非同期ローダー該当なし(ユーティリティ)
AudioAnalyserFFT周波数データの抽出器Audioインスタンスをラップ
重要な警告

ユーザー操作後にAudioContextが再開されていることを確認せずに、絶対にsound.play()を呼び出さないでください。最新のブラウザーでは、ユーザーのジェスチャー(クリック、タップ、キー入力)が発生するまで、AudioContextは必ず一時停止状態になります。

シーンごとに複数のAudioListenerを作成することは絶対に避けてください。複数のリスナーを使用すると、空間化の動作が未定義になります。

ユーザー操作なしで再生されることを期待して、autoplay = trueを設定することは絶対に避けてください。ブラウザーは再生を必ずブロックし、そのことを通知しません。

AudioListenerは必ずカメラに取り付けてください。別のオブジェクトに取り付けると、空間オーディオの計算で誤った基準位置が使われます。

オーディオを再生する前に、ユーザー操作のハンドラー内でlistener.context.resume()を必ず呼び出してください。

AudioLoader.load()のonErrorコールバックを必ず処理してください。エラー処理がない場合、オーディオファイルが見つからなくてもエラーは通知されません。


AudioListenerのセットアップ

AudioListenerはシーンの仮想マイクです。Web Audio APIのAudioContextとAudioDestinationNodeをラップします。

import * as THREE from 'three';

const listener = new THREE.AudioListener();
camera.add( listener ); // ALWAYS add to camera
マスターボリュームの制御
listener.setMasterVolume( 0.8 ); // range [0, 1]
const vol = listener.getMasterVolume(); // returns 0.8
グローバルオーディオフィルター
const filter = listener.context.createBiquadFilter();
filter.type = 'lowpass';
filter.frequency.value = 1000;
listener.setFilter( filter );
// Later: listener.removeFilter();

Audio(非位置依存)

バックグラウンドミュージック、環境音、UIのフィードバック音にはAudioを使用します。リスナーの位置にかかわらず、音量は一定です。

読み込みと再生
const sound = new THREE.Audio( listener );
const audioLoader = new THREE.AudioLoader();

audioLoader.load( 'music.mp3', ( buffer ) => {
    sound.setBuffer( buffer );
    sound.setLoop( true );
    sound.setVolume( 0.5 );
    // Do NOT call sound.play() here — wait for user interaction
});
自動再生ポリシーへの準拠(必須)
document.addEventListener( 'click', () => {
    if ( listener.context.state === 'suspended' ) {
        listener.context.resume();
    }
    if ( !sound.isPlaying ) {
        sound.play();
    }
}, { once: true } );
再生の制御
sound.play();                    // start playback
sound.pause();                   // pause (resume with play())
sound.stop();                    // stop and reset to beginning
sound.setPlaybackRate( 1.5 );   // 1.5x speed
sound.setDetune( -100 );        // pitch down 1 semitone (100 cents)
代替ソース
// HTML5 media element (for streaming large files)
const audioEl = new Audio( 'long-track.mp3' );
sound.setMediaElementSource( audioEl );

// Microphone input
navigator.mediaDevices.getUserMedia( { audio: true } ).then( ( stream ) => {
    sound.setMediaStreamSource( stream );
});

PositionalAudio(3D空間オーディオ)

シーン内の位置に存在するサウンドにはPositionalAudioを使用します。音量とステレオパンニングは、リスナーとの距離や向きに応じて変化します。

基本設定
const positionalSound = new THREE.PositionalAudio( listener );

audioLoader.load( 'engine.ogg', ( buffer ) => {
    positionalSound.setBuffer( buffer );
    positionalSound.setRefDistance( 20 );
    positionalSound.setRolloffFactor( 1 );
    positionalSound.setDistanceModel( 'inverse' );
    positionalSound.setLoop( true );
    positionalSound.setVolume( 0.5 );
});

mesh.add( positionalSound ); // sound position follows the mesh
距離モデルの選択ツリー
モデル使用する場面動作
'inverse'(デフォルト)現実的な環境徐々に減衰しますが、音量がゼロになることはありません
'linear'制御された範囲(例:部屋単位)maxDistanceで音量がゼロになります
'exponential'近距離と遠距離で大きな差をつける場合急激に減衰します

パラメーターの選び方:

  • refDistance — 音量が100%になる距離です。シーンの単位で「快適に聴こえる範囲」に設定します。一般的な値:1~20。
  • maxDistance — 'linear'モデルの場合にのみ関係します。'inverse'と'exponential'では無視されます。
  • rolloffFactor — 音量が低下する速さです。'inverse'では、1が現実的な設定です。'linear'では、1が全範囲を使う設定です。値を大きくすると減衰が速くなります。
指向性オーディオコーン
positionalSound.setDirectionalCone( 180, 360, 0.1 );
// coneInnerAngle: 180° — full volume zone
// coneOuterAngle: 360° — transition zone
// coneOuterGain: 0.1  — volume outside outer cone (10%)

AudioLoader

オーディオファイルの読み込みには、必ずAudioLoaderを使用してください。コールバック経由でAudioBufferを返します。

const loader = new THREE.AudioLoader();

loader.load(
    'sound.ogg',
    ( buffer ) => { sound.setBuffer( buffer ); },   // onLoad
    ( xhr ) => { console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); }, // onProgress
    ( err ) => { console.error( 'Audio load failed:', err ); }  // onError — ALWAYS handle
);

対応フォーマット: MP3、OGG、WAV、AAC。OGGは圧縮率と音質のバランスに最も優れていますが、Safariではサポートされていません。クロスブラウザー互換性を確保するため、MP3も必ず用意してください。


AudioAnalyser

Web Audio APIのAnalyserNodeをラップし、リアルタイムの周波数ビジュアライゼーションを行います。

const analyser = new THREE.AudioAnalyser( sound, 256 );
// fftSize MUST be a power of 2: 32, 64, 128, 256, 512, 1024, 2048

function animate() {
    requestAnimationFrame( animate );

    const data = analyser.getFrequencyData();    // Uint8Array, length = fftSize / 2
    const avg = analyser.getAverageFrequency();  // number (0-255)

    // Drive visuals from audio data
    mesh.scale.y = 1 + avg / 128;
    renderer.render( scene, camera );
}
周波数データの詳細
  • getFrequencyData()は、fftSize / 2個の要素を持つUint8Arrayを返します
  • 各要素の値は0から255の範囲です(デシベル振幅)
  • インデックス0は最も低い周波数、最後のインデックスは最も高い周波数です
  • getAverageFrequency()はすべてのビンの算術平均を返します

統合チェックリスト

  1. AudioListener を1つ作成し、カメラに追加します
  2. リスナーを指定して Audio または PositionalAudio を作成します
  3. AudioLoader で音声を読み込みます
  4. バッファー、音量、ループ、距離のプロパティを設定します
  5. AudioContext を再開するユーザー操作のハンドラーを追加します
  6. ユーザー操作の後にのみ play() を呼び出します
  7. 空間オーディオの場合:PositionalAudio を対象のメッシュの子として追加します

参考リンク

公式ソース

コメント