1 ポイント 投稿者 GN⁺ 2024-09-04 | 1件のコメント | WhatsAppで共有
  • Pong風の音楽ビジュアライゼーションでは、ボールがパドルに当たる瞬間を曲のビートに合わせるため、ゲーム物理を調整し、パドル位置を最適化変数として扱う
  • ボールは一定の速度で動き、パドルはそれぞれ画面の自分側半分のどこへでも移動できる。接触点が反射角を決め、ボールは上下の壁で跳ね返る
  • パドルを中央付近に置けばどんなタイミングにも合わせられるが、画面の活用が小さく動きも単調になり、優れたビジュアライゼーションにするのは難しい
  • 各ビート時点でのパドルの水平位置とボールの水平速度を決め、物理制約と拍を守りながら中央から遠いパドルヒットを最大化する線形計画問題として定式化する
  • 実装では CVXPY で線形制約を解き、解として得られたパドル位置とボール速度から反射角・垂直位置を計算したうえで、キーフレーム補間でアニメーションを作る

Pongを音楽のビートに合わせる物理設定

  • 目標は、古典的アーケードゲーム Pong でボールがパドルに跳ね返る瞬間を曲のビートと同期させ、パドルが音楽に合わせて動くビジュアライゼーションを作ること
  • そのためにゲーム物理の一部を変更する
    • ボールは一定の速度で動く
    • パドルはそれぞれ画面の自分側半分のどこへでも移動できる
  • 従来のPongから維持するルールもある
    • ボールがパドルに当たる接触点が反射角を決める
    • パドルには速度制限がない
    • ボールは画面の上・下の境界で跳ね返る
  • この物理設定により、望む時刻にボールを当てるための自由度が得られる

中央配置による解法の限界

  • 2つのパドルを画面中央近くに置けば、どんなタイミング要求も満たせる
    • 水平方向の空間は小さいが、ボールは上下の壁で跳ね返れるため、垂直方向の空間は事実上十分にある
    • 望むショット継続時間が長ければ、ボールをより垂直に近い角度で打ち、水平速度を遅くできる
  • この方法はすべての入力に対して解が存在することを示すが、見た目としては面白くない
  • 良いビジュアライゼーションには画面空間の活用が重要
    • ゲームが小さな領域に閉じ込められていると窮屈で弱々しく見える
    • 観客は、パドルが届くか届かないかというボールを受けるダイナミックな動きを楽しむ
  • したがって重要なのは、ビートと物理ルールを守りながら、各ビートごとにパドルがどこでボールを打てば画面を広く使えるかである

制約最適化に置き換える

  • この問題は、目的関数、変数、制約条件を持つ制約最適化問題として扱える
    • 目的は画面の活用を大きくすること
    • 変数はボールが跳ね返る位置
    • 制約はゲーム物理と曲のビート
  • 制約最適化として作れば、直接アルゴリズムを設計する代わりに、既存のソルバーで最適なパドル位置を計算できる
  • 物理を変える場合は制約だけを更新すればよく、目的関数も簡単に試せる
  • 2D全体をモデル化する必要はない
    • ボール全体の速度が一定なので、水平速度が決まれば垂直速度も決まる
    • シミュレーションで任意時点のボールの垂直位置を計算できる
    • パドルの垂直位置はボールを当てる必要があるためボールの垂直位置と一致し、望む角度のために小さなデルタが加えられる
    • ヒット間のパドル位置は線形補間で滑らかにつなぐ

入力値と線形制約

  • 固定入力は画面幅とボール速度
    • W: 画面幅
    • S: ボールの速度
  • ビートタイミングはMIDIファイルから得る
    • T = {t_0, t_1, ..., t_n} は、ボールがパドルに当たるべき各ビート時刻
    • 将来的には、オーディオからより自動化された方法で抽出する手法も探索できる
  • 隣接するビート時刻の差から各ショットの継続時間を作る
    • D = {d_0, d_1, ..., d_{n-1}}
    • d_i = t_{i+1} - t_i
  • 最適化変数は水平位置と水平速度
    • P = {p_0, p_1, ..., p_{n-1}} は、パドルがボールを打つときの画面中央からの水平距離
    • 偶数インデックスは左パドル、奇数インデックスは右パドルを表す
    • V = {v_0, v_1, ..., v_{n-1}} は、各ヒット後のボールの水平速度
    • 制約を作りやすくするため、ボールが左または右へ動く方向に関係なく、v_i は常に正の値として定義する
  • 物理制約はパドル位置とボール速度の範囲を定める
    • 0 ≤ p_i ≤ W/2
    • 0 < v_i ≤ S
  • ビート同期制約は、ボールが次のパドルへ正確な時間に到着するようにする
    • p_{i-1} + p_i = d_i v_i
    • 左辺は連続する2回のパドルヒット間の総水平移動距離
    • 右辺はショット継続時間とボールの水平速度の積

目的関数とアニメーション生成

  • 中央に留まる退化解を避けるため、パドルが画面中央から遠ざかるように誘導する
  • 目的関数は、パドルの中央基準距離の合計を最大化する
    • Maximize Σ p_i
  • すべての制約が線形なので、**線形計画法(LP)**ソルバーで解ける
  • 実装には CVXPY を使用する
    • CVXPYは凸最適化問題を解くもので、LPはその部分集合
    • この作業には全機能は必要ないが、より複雑な目的関数や制約をサポートしており、創造的な実験に向いている
  • ソルバーは、パドルがボールを打つべき水平位置とボールの水平速度を返す
    • この値から反射角を計算できる
    • 垂直位置はシミュレーションで計算する
  • 最終的なアニメーションでは、ボールとパドルのヒット時点の位置をキーフレームとして使用する
    • ヒット間では位置を補間し、滑らかな動きを作る
  • コードはオープンソースとして公開されている: Github Repo

1件のコメント

 
GN⁺ 2024-09-04
Hacker News のコメント
  • 20年ほど前、美術展示向けに複数人が同時にプレイするオーディオをコーディングしたプロジェクトを思い出した
    ゲームが激しくなるほど、ボールや壁の音が音楽を奏でていることが見えてきて、3人のプレイヤーが実は1つの曲を一緒に演奏している構造だった
    アーケード筐体3台を互いに向かい合わせに配置し、各プレイヤーは他人の画面を見られないようにして、ボールの速度や方向を少し調整し、音楽的に合う地点でバットや壁に当たって正しい音が鳴るようにしていた
    Josh が自分のサイトに参考として載せているものもある: https://www.autogena.org/work/ping

    • すごい。つまり固定された作曲があって、ゲームプレイをそれに合うように少し調整したということ?
  • このアイデアの変形として、Atari のゲームや Super Mario で強化学習エージェントを訓練しつつ、音楽ベースの報酬や入力を追加して「音楽的」に見えるプレイを作れるのでは、と想像してしまう
    どれほど見栄えがするのか、それだけの価値があるのかはよく分からない

    • 機械学習の初心者だけど、OpenAI がビデオゲームの強化学習向け Python ライブラリを作ったことがあり、そのフォークはいまも活発にメンテされている [1]
      数年前の記憶では、1日か2日、長くても週末くらいあれば動かすところまで行けた。RetroArch エミュレーターを使っていて、非常に多くのエミュレーターとコンソールをサポートしている
      https://github.com/Farama-Foundation/Gymnasium
      Super Mario World で機械学習を扱った SethBling の素晴らしい YouTube 動画もある:
      https://www.youtube.com/watch?v=qv6UVOQ0F44
      自分で試してみることを勧める。最近のAI過熱ムードの中では、ビデオゲームはやや過小評価されている気がするし、機械がゲームをしながらスキルを学ぶことには大きな可能性があると思う。特定のスキルを教えるためにゲームを選んだり、新しく作ったりする可能性も大きい。ただ、その段階になると、オーディオやビジュアルを捨てて、テキストや純粋なデータで機械とやり取りする方がよいかもしれない
      一方で、画像の各ピクセルを入力として与える畳み込みニューラルネットワークの動画を見たことがあるので、音データやスペクトログラムのピクセルで学習しても良い結果が出るかもしれないと思う。音楽に合わせてゲームをプレイしたり、メロディ・ハーモニー・物語に合わせて踊るようにプレイしたりする場面は、確かに面白そうだ
      人間が作ったものはすべて、まず人間の想像の中にあったもので、あなたもそういう脳を持っている。心の中のビジョンを追い、物理的な現実へ引き出すのは美しいことで、人類全体への贈り物のように思える
    • Crypt of the NecroDancer は、キャラクターの動きをリズムに合わせるとゲーム内ボーナスを与える形で、このアイデアを探っている
    • あまり良くはなさそう。Mario には音楽性を強く想起させるほどのリズムが十分にない
      原作の音はフレームレートに結び付いていたので、基本的には少しこういうことが起きていた。その後の PAL 移植版はより遅いフレームレートで動くようになり、この性質が壊れた
  • YouTube のポリリズム可視化を思い出す。良い例は LucidRhythms を見るといい
    https://www.youtube.com/@LucidRhythms
    既存の曲を後から可視化に合わせるのはほぼ不可能だろうけど、異なるバーが異なる音を表し、和音ではボールが分裂するようにすると面白そう

    • パドルを N 個置くのも良さそう。簡単になりすぎないようにパドル同士が近づきすぎたときにコストを与え、各パドルがどの音や拍を担当するかを最適化し、急激な音高変化にもコストを課せば、各パドルが特定の音域に特化できるかもしれない
  • 本当にすごい。拍が進むにつれてパドルが動く様子を見て、見入ってしまった
    見ているだけでしっくり来るものがあり、だから美しく感じるのだが、このプロジェクトはまさにそういうケースだ

  • 先行例: Eisenfunk - Pong (https://www.youtube.com/watch?v=cNAdtkSjSps)

    • それでもかなり違う。その例ではビープ音が一定の速度で鳴るので、映像を曲の BPM に合わせて手動で同期したものだ
      基本的にはキックドラム1つおきに手作りした可視化に近い
      一方、投稿された作品では音が単純な4分音符のテンポ上にあるわけではなく、制約最適化に基づいて自動で「アニメーション」されている。だから可視化もずっと興味深いものになっている
  • 本当に良い。ただ、購読しないとハートを送れないので、自分には少し合わない感じがする

  • 技術的には悪くないが、パドルとボールがほぼ同じ速度で動いていて、パドルがずっとボールを押しているように見える場面が何度もある
    この理由から p[i] = 0 は許可しない方がよい。大きな d[i] の直後に非常に小さい d[i+1] が来ると避けられないだろうが、可能な場合には避けるようにできそうだ

    • 目的関数に d'[i] に比例するペナルティを与えればよい
  • 自分の空間に installation を置き、MT-80S とディスプレイを一緒に使うところを想像してしまう
    このタイミングを自分はちゃんと理解できるだろうか? こちら方面に賢いわけではないけれど、興味はある
    https://www.matrixsynth.com/2014/07/roland-mt-80s-midi-playe...

  • 本当に興味深いのだが、不思議なことに自分の脳はこれをものすごく嫌がる
    自分の中の因果関係モデルのようなものを刺激している気がして、見づらく感じる。妙だ

    • 自分にとって最も目立って欠けているのは強弱だ。特に速いパッセージで、ずっと大きな音の間に「ゴーストノート」があるとき、何かが抜けているように感じる
      とはいえ、不思議と見ている満足感はある。複数の楽器を演奏した経験が、この感覚と関係しているのかも気になる。自分には、シロフォンやスティールパンのような楽器がこれにかなり近く感じられる
    • ボールがパドルの端ではなく中央で跳ね返っているように見えるので、ずっと違和感がある。たぶん同じ問題を見ているのかもしれない
  • Atari には1970年代後半にビデオ音楽可視化装置があった。Pong のゲーム開発者の1人が設計したもので、この種の消費者向け製品としては最初、あるいはその1つだった
    https://en.wikipedia.org/wiki/Atari_Video_Music
    映画 Over the Edge を見たことがあるなら、Claude と Johnny が家に1台持っている