Open8

Particle System OpenGL ES

scnshscnsh

https://www.raywenderlich.com/2704-opengl-es-particle-system-tutorial-part-1-3
をまとめる
ただし、このチュートリアルは GLKitありき

Particle System とは

2つのレベルで考える

  • ソースもしくは生成器となる emitter があり、パーティクルのふるまい全体を制御する
  • particle 自体は、小さなオブジェクトの集合であり、それぞれが非常に似通った特性を持つ、ただしそれぞれが独立した物体である

降水量 がパーティクルシステムの良い例となる。最初に雲が存在して、それがシステムの emitter となる。天候によって、雲は雨・雹・雪を生成し、それらがパーティクルとなる。
他に議論する項目として、point sprites が存在する

Point Sprites とは

スプライトは、シーン内にあるスタンドアローンな 2D 画像のことをCGでは呼ぶ。
例えば、テトリスの単一のブロックはスプラインとであり、スーパーマリオのコインも同じである。グラフィックスアプリケーションを作ったことがあれば、スプライトが四角形のテクスチャであり、2Dテクスチャの長方形領域を作る2つの三角形からつくられていると知っているだろう。

三角形ベースで実装された四角形のテクスチャは最低でも4つの頂点が1つのスプライトに必要となる。パーティクルシステムは100個単位のユニットで通常扱われ、すなわち大量の頂点が存在する。
OpenGL ES 2.0 では、ありがたいことに、GL_POINTS を使って簡単にスプライトを描画できる。このコマンドがGPUに各頂点を四角形のポイントで描画して、スプライトに対して4頂点が必要な場合に1頂点で済むようにしている。

GL_TRIANGLES は 塗りつぶされた三角形を、GL_LINES は 線分を描画するが、GL_POINTS は 全く違うものであり、単一の点(テクスチャを適用済み)を描画する。

scnshscnsh
scnshscnsh

いい感じに動作確認できたので中身を確認していく

scnshscnsh

Chapter13を見てるけど、Commonの関数を結構使ってそう。
最小限必要な部分だけとりだしたい

  • esLoadTGA : TGAファイルの読み出し

  • esLogMessage: エラー出力

  • esLoadProgram: シェーダーの読み込み

  • ESContext

    • ユーザーデータ置き場 (voidポインタで参照できるようにしている)
    • 他にはウインドウのプロパティとか置いてる
  • esInitContext: 初期化

  • esCreateWindow: ウインドウ作成

  • esRegisterDrawFunc: es描画関数の登録

  • esRegisterUpdateFunc: アップデート関数の登録

  • esMainLoop: メインループ関数

  • UserData構造体

    • particleのデータをまとめて保持している
    • lifetimeとか
scnshscnsh

処理の流れ

  • Init()

    • シェーダーファイル(fragment/vertex)を読み込ませる
    • userDataを設定(パーティクルに使うパラメータ)
      • シェーダプログラムとの対応付けもやる
      • glGetAttribLocationで対応する変数を教える
      • glGetUniformLocationでuniform変数も伝える
    • パーティクルのランダム値(初期値)を生成
    • パーティクル用テクスチャのロード
  • Update()

    • 1秒ごとに以下の処理を実行
      • 開始地点と色をリセット
    • 時間経過に従ってパーティクルを更新
  • Draw()

    • 描画領域をリセット
    • シェーダープログラムを読み込む
    • 各点群に対してパラメータを割り当て
      • glVertexAttribPointerでデータ格納場所を伝える
      • glEnableVertexAttribArray で変数に頂点情報を対応付ける