Babylon.js のパーティクルシステムでビルボードモード（BillBoard Mode）を変更してみる

## はじめに
Babylon.js のパーティクルシステムについて、Qiita に記事をいくつか書いたのですが、その際に見かけていた「ビルボードモード（BillBoard Mode）」が気になったので、記事に書いてみます。

## ビルボードとは？
ビルボードとは、以下の記事の記載から引用すると、「カメラの視線ベクトルに対し常に垂直な姿勢を持つようにモデルをレンダリングすること」となります。

●wgld.org | WebGL: クォータニオンとビルボード |
　https://wgld.org/d/webgl/w035.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6c039837-6bfc-a478-81bd-8433bd051687.png)

例えば、板状のポリゴンにテクスチャを貼っている状況で考えると、カメラに対して常にポリゴンが正面を向くので、カメラの方向によらずテクスチャが常に見える状態になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/09338a6c-3644-64d5-8033-55949ec42ded.png)

これにより、平面に描かれたテクスチャを用いているにもかかわらず、3D空間内でカメラが視点を変えても、多方向からそのテクスチャが閲覧可能になります。

3Dモデルを作成して利用するより、描画コストを下げられるといったメリットがあるようです。
3Dモデルを使って描画した場合と比べて、見た目に違いが生じるというのはありますが、いろいろ活用できる手法のようです。

### Babylon.js以外でのビルボードの話
Babylon.js以外でも、例えば Blender や Unity などでも、このビルボードという話は登場します。

●【Blender】ビルボードで草束を表現｜yugaki
　https://note.com/info_/n/n5032190fcde6

●【Unity】ビルボードで常にカメラの方に向く木を作る - おもちゃラボ
　https://nn-hokuson.hatenablog.com/entry/2017/03/24/211211

## Babylon.js のパーティクルシステムでのビルボードモード
Babylon.js のパーティクルシステムで、ビルボードの適用方法（ビルボードモード）に関する設定が行えます。

### パーティクルシステムでのビルボードモードの種類
パーティクルシステムでのビルボードモードの種類について、公式ドキュメントの以下の部分に記載されています。

●ParticleSystem | Babylon.js Documentation
　https://doc.babylonjs.com/typedoc/classes/BABYLON.ParticleSystem

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c0d042c7-ca79-6ba1-96b1-58fde831d733.png)

ビルボードモードを利用する場合、以下の 4パターンのモードを指定できるようです。

- BILLBOARDMODE_ALL
   - Billboard mode will apply to all axes
- BILLBOARDMODE_STRETCHED
   - Special billboard mode where the particle will be biilboard to the camera but rotated to align with direction
- BILLBOARDMODE_STRETCHED_LOCAL
   - Special billboard mode where the particle will be billboard to the camera but only around the axis of the direction of particle emission
- BILLBOARDMODE_Y
   - Billboard mode will only apply to Y axis

それぞれの説明を見てみると、ビルボードの向き変更を適用する軸を Y軸のみにするか、もしくは全ての軸にするかや、その他にパーティクルの設定に依存したものになるかなどといった違いがあるようです。

### ビルボードモードのデフォルト値
公式ドキュメントの以下を見てみると、パーティクルシステムでビルボードモードを指定しない場合、ビルボードを利用した描画が用いられるようです。
具体的には、「BILLBOARDMODE_ALL」が適用されていると思われます。

●Color Ramps, Blends, and Billboard Mode | Babylon.js Documentation
　https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/ramps_and_blends#billboard-modes

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9559a47e-fef0-e310-985c-2538ff12f2d5.png)

## Babylon.js のパーティクルシステムでビルボードモードを使ってみる
### お試し その1
それでは、以下の公式サンプルを使って、ビルボードモードを変更した時にどのような見た目の違いが生じるかを確認してみます。

●Particle System Examples | Babylon.js Playground
　https://playground.babylonjs.com/#0K3AQ2#42

#### BILLBOARDMODE_ALL
以下が特に何も指定をしないデフォルトの状態（「BILLBOARDMODE_ALL」になっている状態）です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/2633749b-fb40-2052-c523-9d7b6ee0c268.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d356a5b8-17c2-2d1c-f879-085eb891b913.png)

上記はデフォルトの視点と、上からの視点です。

#### ビルボードモードをオフにする
`particleSystem.isBillboardBased = false` として、ビルボードモードをオフにしてみます。

以下のように、デフォルトの視点では板を横からみたような見た目になり、上から見るとテクスチャが分かる見た目になりました（それと、色についても見た目が変わってしまっている...）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/920f4ced-3bcc-8216-3f1a-2154d0ffe89f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/95ec5943-e376-9ab8-cb49-48bb5e30470e.png)

#### BILLBOARDMODE_Y
次に `particleSystem.billboardMode = BABYLON.ParticleSystem.BILLBOARDMODE_Y` という指定を加えてみます。

そうすると、以下のように視点を上からに変えたときは、その方向がビルボードの向きを変える対象の方向ではないため、板を横から見たような見た目になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/07cb4502-e2b4-2931-578d-298d865c51d0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ea2165cd-d144-999a-6746-bc6be3b5b3d9.png)

#### 残りの 2つのビルボードモードについて
残りの 2つ（BILLBOARDMODE_STRETCHED、BILLBOARDMODE_STRETCHED_LOCAL）も試してみました。

BILLBOARDMODE_STRETCHED は BILLBOARDMODE_ALL と同じような見た目になったように思えて、また BILLBOARDMODE_STRETCHED_LOCAL は BILLBOARDMODE_Y と同じ見た目になっていた感じでした。
上記の異なるモード間で見た目に違いが出てないように見えるのは、用いたパーティクルシステムの設定によるものかもしれません（または、自分が気づけていないだけ？）。

### お試し その2
別の公式サンプルでも試してみます。今度は、以下のサンプルを使ってみます。

●Sun Particle System | Babylon.js Playground
　https://playground.babylonjs.com/#EV0SEQ

#### ビルボードモードをオフにした状態
上記の公式サンプルは、明示的にビルボードモードをオフにした状態になっています。

その状態だと、以下のようにテクスチャが、球面の表面の法線方向に向いているような見た目になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/7fe9bc61-4810-281a-662b-05e26f4f00da.png)

#### BILLBOARDMODE_ALL
次に BILLBOARDMODE_ALL を設定してみます（※ ビルボードモードをオフにしている行をコメントアウトしました）。

そうすると、視点を変更しても、以下のようにテクスチャが全てカメラ方向に向いて見えるような形になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/cf400fdb-93de-593c-d21e-7daec5878e76.png)

#### BILLBOARDMODE_Y
BILLBOARDMODE_Y を試してみます。
この場合は、上から見た時は、以下のようにビルボードの向きが変わらない状態になりました。
※ 横から見た時は、BILLBOARDMODE_ALL と同じ見た目

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d553c90e-b7f9-9d6f-f03a-87f40a1b5389.png)

#### 残りの 2つのビルボードモードについて
残りの 2つ（BILLBOARDMODE_STRETCHED、BILLBOARDMODE_STRETCHED_LOCAL）も試してみました。

その場合は、どちらも何も描画がされていない状態になりました。

BILLBOARDMODE_STRETCHED・BILLBOARDMODE_STRETCHED_LOCAL の 2つは、公式ドキュメントの説明で「rotated to align with direction」「only around the axis of the direction of particle emission」といった記載がありました。

2つ目のサンプルは、パーティクルが特定方向に放出されるような動きではないため、1つ目のサンプルと違って BILLBOARDMODE_STRETCHED・BILLBOARDMODE_STRETCHED_LOCAL の 2つは、何も描画されてないような見た目になったと思われます。

#### 残りの 2つのビルボードモードの特徴を ChatGPT に聞いてみた
ここで ChatGPT に聞いてみると、以下の回答が得られました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/2e53565b-814a-8bc5-40aa-1079e0a5958b.png)

これを参考にすると、BILLBOARDMODE_STRETCHED・BILLBOARDMODE_STRETCHED_LOCAL の 2つで、見た目の違いを生じさせるようなパーティクルシステムの内容・設定が分かりそうです。

そもそも、ChatGPT の回答が正しいことを言っていそうかどうかの確認も含め、3つ目のお試し用のサンプルを見つけて、ビルボードモードのお試しをやっていきます。

### お試し その3
Babylon.js のパーティクルシステムの事例を探していると、以下の @Limes さんのブログ記事でちょうど雨のようなエフェクトがありました。
BILLBOARDMODE_STRETCHED・BILLBOARDMODE_STRETCHED_LOCAL の 2つが、それぞれ影響を及ぼしそうに思われたので、これで違いを見てみます。

●Babylon.jsのパーティクルをGUIで設定できるParticle Editorを使って、いくつかエフェクトをつくってみました - CrossRoad
　https://www.crossroad-tech.com/entry/babylonjs-particle-editor-jp

●shiny rain | Babylon.js Playground
　https://www.babylonjs-playground.com/#0MB0GU

以下に、4つのモードを使った場合の、デフォルトの視点と上から見た時の状態を掲載してみます。

#### BILLBOARDMODE_ALL
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e3735d25-b4ed-5697-352c-a2aa6c5db6ff.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/86f1157a-3fc9-6273-9691-63faf889f355.png)

#### BILLBOARDMODE_Y
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9bf44a84-78a8-eddd-ba09-3c1a0659dc88.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/790aa27f-7125-d5e4-f9ae-f51b738d18cb.png)

#### BILLBOARDMODE_STRETCHED
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/49d828d5-2aa3-64ca-256a-750562ad53ca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6aaf6d4b-0a51-a557-0872-e23419e3e66c.png)

#### BILLBOARDMODE_STRETCHED_LOCAL
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/aa08f910-1cd0-f99d-ebb7-5fe3172eca6e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/65e33e2f-4b6e-645b-a0d0-01b2eee02265.png)

想定通り、上記を使って試した場合は、BILLBOARDMODE_STRETCHED・BILLBOARDMODE_STRETCHED_LOCAL の 2つを使った時の描画の見た目が、他の 2つのモードとは違ったものになりました。

ただし今の時点では、自分は BILLBOARDMODE_STRETCHED・BILLBOARDMODE_STRETCHED_LOCAL の 2つの特徴をどう活かすかが分かっていない状況です。このあたりは、もう少し深掘りできればと思います。