AtomでGLSLをライブコーディングできるパッケージを作ったりしています。今日はShadertoyのコードを読んで、Three.jsで真似してみる、ということをやってみました。経緯ShadertoyにはGLSLで音声を出力できる機能があります。デモ用の効果音を生成したり、以下のようにガッチリ曲を作ったりできます。いうわけで、Shadertoyのコードを読みつつ、ちゃんと理解するためにThree.jsで実装してみました。Shaderは、以下の2つのメソッドを読むと仕組みが分かります。Shaderを実行するための準備を行っています。xが左、yが右チャンネルです。Shaderに、main関数を含む文字列を結合します。main関数を読むと、ピクセルごとに異なる引数でmainSoundを呼び出していることがわかります。あることがわかります。SoundShaderは1回のレンダリングで約6秒の音声データを作成できるようですね。Shaderが生成できる音声には180秒までの制限があるようです。1900行目〜)Paint_Soundは、シェーダーの変更後はじめてPaintが実行されたとき呼ばれるようになっています。Paint_Soundは1回の実行で180秒分の音声データをすべて作成します。uniform変数をガチャガチャ設定してる部分はどうでもいいので読み飛ばすと、forループがネストした箇所が見つかります(2053行目〜)。ここが音声生成のコア部分です。やってることは単純です。外側のループは、180秒分の音声データが生成し終わるまでレンダリングを繰り返す、というループです。内側のループでは、レンダリング結果の各ピクセルの値を音声データに変換し、AudioBufferに詰める、ということをやっています。とある通り、一つのサンプルを2バイトで表現しています。以下のように上位ビットと下位ビットに分けて出力していることがわかります。丸められてしまい、音声として使い物にならないという問題があったのだと思います。b+aの2バイトを使って表現することで、より精度の高い音声出力を実現したのでしょう。ループが終わったら、AudioBufferSourceNodeをstartして、音声を再生しています。感想Three.jsでもシュッと実装できて楽しかった。あとShadertoyのコード意外と読みやすい。やり方はわかったので、VEDAにも機能追加しようと思います。音声をループ再生したり、音声の長さを指定できたりすると、ライブコーディングでの音楽パフォーマンスが楽しくなりそうですね。3Dモデル読み込み、Floatテクスチャ、全画面モードこんにちはアマギです。法然院でVJした過去記事スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。