2008-07-15

[]XNAで反応拡散方程式を動かしてみた XNAで反応拡散方程式を動かしてみた - Nao_uの日記 を含むブックマーク はてなブックマーク - XNAで反応拡散方程式を動かしてみた - Nao_uの日記 XNAで反応拡散方程式を動かしてみた - Nao_uの日記 のブックマークコメント

以前に作った反応拡散方程式を動かすデモXNAに移植して、せっかくD端子のキャプチャーボードがあるのでXbox360からの出力を動画に落としてみた。

今回は計算にはCPUは一切使わず、浮動小数バッファを2枚つかってすべてGPUに計算させている。

さすがにXbox360GPUは強力で、テクスチャフェッチが5回とそれなりの量の計算をしてる重めのシェーダーを、640*360ドットの解像度で早回しのために1フレームに32回ループさせても平気で60fpsで動いている。64回回すとさすがに処理落ちしたけど、32回でも十分早すぎるくらいに滑らかに動いているので、Flash版では変化が遅すぎて使えなかった組み合わせのパラメータも実用的な速度でアニメーションしてくれる。

あいかわらずパラメータ調整は難しいけど、動画の倍速再生をしなくてもリアルタイムで滑らかに動くのは気持ちいい。

プログラム自体はFlashから移植するだけなので簡単にできるだろう、と思ってたのに予想外に時間がかかってしまった。以下、今回のハマりポイント。

  • Vector4をレンダーターゲットとして作ると、なぜか内部でBgr32扱いのテクスチャとして作られてしまう
    • ハードウェアがVector4のレンダリングには非対応なせいかも?今回の用途ではVecter2で問題なかったのでそちらに切り替えることで対処。
  • αブレンドを切らないと正常に動かない
    • これもおそらくハードウェアが未対応なため?明示的にOFFにする必要がある。
  • サンプラステートでミップフィルタをPOINTにしないと動かない
    • エフェクトファイル側に書いておかなくてはいけない。これに気づくのに一番時間がかかった・・・。

結局、Vector4はテクスチャとして読むことはできても描くことはできないことと、floatのバッファはαブレンドができなくてバイリニアフィルタもかからないので、そのように設定しておかないと正常に動いてくれない、というのが原因だったっぽい。

設定ミスがあっても色化けなどのおかしな動作になるだけで特にエラー表示なども出ないため、シェーダーの書き間違いを先に疑ってしまって原因に気づくのにかなり時間を食ってしまった。

XNAではCPU側が重くなってGPUが遊びがちになる傾向があるようなので、同じものを複数描画したり、大規模な単純計算を行うときにはGPU内で完結させるGPGPU的なやり方が向いてるように思う。ピクセルシェーダー・バーテックスシェーダーともにかなり高速なGPUを積んでるので、わりと無茶な使い方をしてもそれなりに動いてくれる。

少しクセはあるものの、hlslで書けるので慣れればそこまで面倒でもなさそう。今回の応用でパーティクル表示くらいなら、バッファの取り扱いにさえ気をつければ比較的簡単に作れそうなので、そちらもいずれ試してみたい。