ひとまず条件付きでできたので、アップロード。
mmdviewリポジトリのparticleブランチ
コミットNo: 94b7ed9a81ab6d54c8f721a71db4b89ca6bf47b0
中心から放射状に広がるパーティクル
見ていて飽きない。特に背景真っ黒だから、加算半透明が綺麗。
動かしてみるとこんな感じ。
コード中で使っている関数の説明
パーティクル用のパラメータ設定の関数を記載。
glDisable(GL_DEPTH_TEST);
深度テストを無効にする。いわゆるZバッファの無効化。
本来ならば、一番奥にある半透明オブジェクトからレンダリングしていくべきだが、今回はこれで暫定対処。
glEnable(GL_BLEND);
アルファブレンディングによる半透明を有効にする。
glDisable(GL_APLHA_TEST);
アルファテストを無効化する。アルファテストは、アルファ値の比較でレンダリングする/しないを判断する機能。
今回はアルファブレンドで加算半透明だけやりたいので切っておく。
glBlendFunc(GL_SRC_APLHA, GL_ONE);
加算半透明のパラメータ。他にも減算とか乗算とか色々ある。
今回は光を表現したいので、加算半透明で。
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
半透明の演算方法を指定する。
テクスチャのα値とプリミティブのα値をどのように扱うかがここで決まる。
これが一番自然に見える設定っぽい。
パーティクルの変換行列の設定
glTranslatef(px, py, pz);
座標の設定。今回のパーティクルは中心部から放出されるようなものを表現したかったので、px,pyに対して移動速度をランダムに設定してあげるだけでそれっぽい感じに。
float mx, my;という移動速度用の変数をもっておき、
mx = rand() % 50;
mx *= 0.01f;として、適当な範囲の乱数を求める。
そして
px += mx; py += my;
の演算を毎フレーム実行する
glScalef(sx, sy, sz);
スケールの設定。これにより各パーティクルの大きさを決める。
各粒子は
- 出現時に大きさ確定する
- 出現時の大きさはある程度の乱数の範囲内に絞る
- 出現後の大きさは固定とする
コードとしては
float scale = (rand() % 100) * 0.01f;
sx = sy = sz = scale +0.1f;
ここで0.1が最小サイズ、上限が1.10fあたり。
その他こまごまとやったこと
テクスチャをBMP形式で読んできているので、αチャネルが存在しない。
そこで、RGB各チャネルの平均をα値として使うことにした。
テクスチャ読み込み後のコードに対して単純にRGBごとの演算をしてあげた。
パーティクルの素材作り
こればっかりはプログラマには向いてない。致命的なくらいに。
グラデーションを生成するくらいはできるけども、素材を色々と試したいときは手間が多い。
フォトショップ欲しいなぁ。
さて、気楽に光を表現するためのパーティクル作れるツールないかなと探していたところ、「きらきら筆」というツールの存在を思い出したので早速使わせてもらいました。
結構古いツールだけども、ちょっとした素材を作るという今回の目的は十分すぎるくらい達成してくれました。
感想・今後の展望
やっぱりパーティクルは綺麗だし見ていて楽しい。
今ある制約を取り払って色々な環境で動くようにしたい。
修正していくつもりなので、今ある制約メモ
- ビルボードにしたい。カメラの位置が変わっても板ポリゴンだとわからないようにしたい
- 頂点色の設定をできるようにして、魔法の属性ごとに色を替えるとかやりたい
- パターンをもっと増やしたい。例えば爆風とか、光のシャワーとか
- あ。BMPコミットしてしもうた。バイナリはgithubに入れたくない
というわけで今回はこんなところで。