~下の画像をクリックすると、パーティクルが飛び跳ねるアニメーションが見られます。■はじめにまた、spinネタで恐縮ですが、GPUを使ったパーティクルの時間発展のプログラムです。あとは最終的なフレームバッファへのレンダリングまでGPUにお任せするのが基本的な流れになっています。データの流れは、CPUからGPUに一方的に流れるものであって、GPUからCPUへのデータの流れは考えられていません。CPUでGPUの結果を使うためには、GPUで作成したテクスチャをロックしてから読み込む手順が必要になります。この方法は、本来のデータの流れとは違うものなので、処理は非常に低速です。パーティクルの時間発展までGPUにやらせようという考えが自然に浮かんできます。Engine』などのそれらに関する論文が提出されています。それらの方法とは違う方法になりますが、GPUを使ってパーティクルを飛ばしてみます。今回のプログラムは、次のものです。HALで実行できる環境はこの世には存在しません。パーティクル:DirectX9)まぁ、いつものように適当にファイルが入っています。出力されるフレームワークのファイルは紹介を省かせていただきます。アプリケーションのソースあと、実行ファイル、モデル及び、プロジェクトファイルが入っています。強力な超SIMD計算機だということが認識されるようになって来ました。配列全てに関して一度に同じ計算ができるということです。非常に多くのパーティクルの計算を一度に行うことです。今回は、まさにその方法を実践します。とでも名づけましょう)。テクスチャの一番上の段に位置座標、2段目に速度、そして3段目に加速度を準備します。別のパーティクルは横に並べます。今回は、64個のパーティクルを飛ばしました。今回は、それぞれのテクセルについて、0.5の色値をベクトルの0にする。符号化スケーリングの方法を取りました。これは、ディスプレースメントマッピングのテクスチャが読み込まれた時の値の範囲が0~1の間にクランプされてしまったので、0.5を中心に持ってくるようにするためです。並べておくと、何がいいかというと、それぞれのテクセルの下の段は、その変数の時間微分になっているので、縦にずらしたテクスチャを重ねるだけで、パーティクルの時間発展が可能になります。時間発展の計算が次のようなポリゴンを1枚張る計算で済んでしまいます。);シェーダを使っているのは、ベクトルの0点を0にするために、少し計算が必要だったからで、基本的には、加算合成です。ちなみに、つかっているシェーダは次のようになります。}まぁ、実際には、0.5でなくて、0.502を引いてベクトルの0点を合わせています。この0.002の違いは、よく分かりません。実際の動きを見て値を調整しました。その時間差を掛けておいて足しこむと、より良くなると思います。実際にパーティクルを動かすのは、現時点では他に方法が無いので、ディスプレースメントマッピングを使いました。ディスプレースメントマッピングでは、HLSLが使えないので、じみちにアセンブラを書きます。頂点データでは、読み込んだディスプレースメントマップの値を符号化スケーリングして頂点座標に足しこみます。動ける範囲がこの範囲よりも大きい場合は、ディスレースメントマップの値を適当にスケーリングして使います。};描画するときには、テッセレータをNパッチにしてから描画します。図では「点」を表示しているように見えますが、普通にメッシュを表示しています。m_pEffect->End();なお、メッシュには、パーティクルごとに専用のものを用意しています。違いは、ディスプレースメントマップを指定するテクスチャ座標です。位置座標を指定します。作ればディスプレースメントマップのデータだけを別にできると思います。■初期化や値のリセットあと、必ず必要になってくるのが初期化です。パーティクスの位置の初期化などは、対応するテクセルにポリゴンを上塗りすることによって可能です。今回は、位置と速度に関して同じような乱数を使って、テクセルの一つ一つを塗りつぶすことによって初期化しました。初期値は、精度が落ちないようにピクセルシェーダの定数としてシェーダに渡しました。このように1点1点づつ設定するならば、ポリゴンでなくて、ポイントリストを使ったほうが効率的かもしれません。m_pEffect->End();ピクセルシェーダでは、単純に定数を出力します。毎フレーム、加速度を与える部分があります。一般的な場合を考えて、毎フレーム初期化しました。GPUによるパイプラインの並列動作の効果を授受できます。);ちなみに、y成分だけ塗りつぶすときの値が小さくなっています。これは、下方向に重力加速度をつけるためのものです。当たり判定をいれて、飛ばないようにします。今回は、[-1,+1]の大きさの箱の中にパーティクルを閉じ込めました。閉じ込めるために2つの処理をします。1.箱の外にいたら速度ベクトルの向きを反転する2.箱の外にいたら壁までパーティクルを押し戻す。ちなみに、1と2の順番は入れ替えることができません。「外にいた」と判定されなくなる可能性があるからです。それぞれの過程は、テクスチャの位置と速度のそれぞれの部分にポリゴンを張ることによって処理されます。);ともに、テクスチャ座標の1つめに、パーティクルの位置座標、2つめに速度を指定して描画します。それぞれのパスで指定されたシェーダの中身が当たり判定のみそです。いってもそれほど複雑ではありません。単純に成分ごとに外にあるかどうかを判定して、外に出ていたら、それなりの処理をするだけです。1つめの速度の場合には、成分ごとにはみ出たら向きを変えます。速さがどんどん速くなってしまうので、跳ね返り定数を入れて発散を押さえるようにしています。}位置のほうも、はみ出ていたら、境界部分に位置をクランプするようにします。当たり判定シェーダの技術を応用すれば、より複雑な地形に対して当たり判定を行なうことができます。それはのちのち紹介していきます。■最後にということで、GPUを使ったパーティクルの計算です。重いので正当な評価はできませんが、それは、vs_3_0が使えるようになる時までとっておきましょう。それにしても、OpenGLだと、このレベルのシェーダがリアルタイムに実行できるんですよね。最新のAPIがOpenGLだというのは、変な時代になりました。もどるimagire@gmail.com。