ひとことで
粒子の発生位置を、点や箱ではなくメッシュの表面上から選ぶ放出方法です。燃える物体の輪郭から火の粉を出す、キャラクターが砂になって崩れる、魔法のオーラが体の表面から立ち上る、といった「その形に沿った」エフェクトを作れます。
ゲームでの使いどころ
- 燃焼・炎上:燃えている木箱や敵の体全体から炎と火の粉を出す。
- 消滅・崩壊:倒した敵が砂や光の粒になって崩れる(ディゾルブと組み合わせるのが定番)。
- バフ・状態異常のオーラ:キャラクターの表面から立ち上る光や毒の泡。
- 出現演出:粒子が集まって形を作る(逆再生)。
しくみ
素朴に考えると「頂点からランダムに選ぶ」方法がありますが、メッシュの頂点はモデリングの都合で偏って配置されているため、放出も偏ります。デモの UV 球は極に頂点が集中しているので、頂点から選ぶと極ばかりから粒子が出てしまいます。
表面上で一様に選ぶには、2 段階の抽選をします。
- 三角形を面積に比例した確率で選ぶ:各三角形の面積の累積和の表を作り、 の乱数を二分探索する(逆 CDF 法)。
- 三角形の内部から一様に 1 点を選ぶ:2 つの乱数 を取り、 なら と折り返して、
これで、メッシュの分割の粗密に関係なく、見た目の面積どおりに放出できます。法線も三角形から補間して取得し、粒子の初速を法線方向に向けると「表面から湧き上がる」動きになります。
実装のポイント
- スキンメッシュの場合:アニメーションで変形するキャラクターから放出するには、選んだ三角形の頂点をその時点のスキニング結果で計算します。三角形の選択表は変形前のもので近似するのが一般的です。
- 放出密度をテクスチャで制御:「胴体からは多く、手足からは少なく」のように、頂点カラーやテクスチャで重みを掛けると表現の自由度が上がります。これは重要度サンプリングの考え方そのものです。
- three.js:
MeshSurfaceSampler(three/addons/math)が、面積で重み付けした表面サンプリングを提供しています。
つまずきやすい点
- 頂点から選んでしまう:実装が簡単なので最初にやりがちですが、偏りの原因になります。
- 小さすぎる三角形の扱い:面積 0 の三角形(縮退三角形)は、累積表で幅 0 になり選ばれませんが、法線の計算で 0 除算になることがあります。
- 内側の面:服の裏地や口の中など、見えない面からも放出されます。放出用に簡略化したメッシュを別に用意することもあります。
デモで試すこと
- 「放出位置の選び方」を頂点からランダムにすると、球の上下の極から粒子が噴き出します。左下の数値で、極付近の割合が面積どおりの約 20% を大きく超えることが確認できます。
- 面積で重み付けした三角形に戻すと、表面全体から均等に燃え上がり、割合も約 20% になります。
- 「メッシュの頂点と辺を表示」で、UV 球の分割が極ほど細かいことを確認してください。