【blender】ジオメトリーノードを用いた爆発の表現【軽い】

こんなかんじ
![0076-0096.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/c888f117-8c9a-c9dc-4e1a-a6e2f6877bc4.gif)
エフェクトをつけるともっと爆発っぽくなると思います
![別角度.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/1a68abb6-1a04-bb13-8ac2-0cd692ffec18.gif)
爆発というより爆散かも

#### 利点
blenderでオブジェクトの爆散を表現する方法として、
・物理演算を使った方法
・破片をひとつひとつキーイングする方法
などがあると思いますが、物理演算は重いしキーイングはめちゃ大変です

今回の方法は物理演算より軽く、自力キーイングより楽だと思います

環境：blender3.3

### 作り方
##### オブジェクトを分割し、コレクションにまとめる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/b9bed100-f5b2-64fd-a87b-a430c0de28e7.png)
分割は自力でもいいですが、[Cell Fracture](https://bluebirdofoz.hatenablog.com/entry/2020/07/03/225143)アドオンがおすすめです

分割ができたら、オブジェクトの塊ごとにコレクションを作ってまとめます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/f524ad3f-3af2-e9c5-13b7-913e192213c4.png)
（firstDが”破”、secondDが”壊”）

##### 制御用のオブジェクトを用意する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/3c257dc7-74f2-f41b-266d-717f1815e161.png)
なんでもいいです
今回はEmptyからplane axisを用意し、**destroyer**と名付けました

##### ジオメトリーノードで爆散
ジオメトリーノード用のオブジェクトを作って（なんでもいいです）そいつのジオメトリーノードタブでノードを組んでいきましょう

ノード群の全貌はこんな感じです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/d0785739-9fd6-38c4-e0e5-089a1e5f2d46.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/e24124ce-3cb2-a9f8-e759-f52cf486371d.png)
１枚目が全体図、２枚目がdestroy first/secondの中身です
destroy firstとsecondは全く同じものです

(Ctrl+Gでノードのグループ化を行うことができます)
参考：[Blender: ノードグループ（Node Group）の使用方法](https://reflectorange.net/archives/198.html)

２枚目について詳しく見ていきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/bba44b50-7552-6467-1333-345346c0035b.png)
Object Infoノードから先ほどつくった制御用のオブジェクト **destroyer** のScaleを取得し、Separate XYZノードによってベクトルを分割します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/e97e7304-c1ee-90e5-656a-dd964d32bad7.png)
取得した値をFloat Curveノードにつっこんで、グラフをこんな感じにします
Float Curveノードは横軸が入力値、縦軸が出力値のグラフをつくります
０から１の値をとります

XYZでやることは同じなので、Y,Zも同様にやります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/01edfeec-42c9-5639-adc7-43bacb21bc4b.png)
Float Curveノードから取得した値をMultipyでn倍（n=散逸の範囲を表すパラメータ）して、Addで１（これは固定）を足します
同様に操作したX,Y,ZをCombine XYZで再びVector化します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/6c95de4b-ddb6-1ad9-ea9b-471f58249f7d.png)
ここがメインの部分です
各ノードについての説明：
* Combine XYZ：**destroyer**のScaleから取得した、各破片の移動量係数ベクトル
* Position：各破片（Collection内のObject）のもともとの位置
* Multipy：ベクトルの各要素の積をとる。アダマール積というらしい
* Group Input：入力したCollection
* Group Output：結果。起こる事象

各破片のワールド原点からのベクトルと、移動係数ベクトルとの要素積をとることで各破片の移動先を決定します

あとは移動先の位置をSet Positionに入れとけばOKです

**爆発の中心をワールド原点から変えたい場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/fcc3aebf-e5e0-0a8d-c1d6-829a42bdabdb.png)
Centerは爆発の中心となるオブジェクトです
例のごとくEmptyでも置いときましょう
もちろん、位置ベクトルを入れて直接指定することもできます

##### 制御の仕方
**destroyer**のScaleによって制御しているので、それをキーイングすることでアニメーションをつくれます
注意点として、Float Curveノードの範囲が０から１なので、Scaleもそれに合わせる必要があります
Multipyノードの倍率で大きさを決めましょう

ーーーーーーーーーーーーーーーーーーーーーーーーーーー

以上です
物理演算ほどリアルには動きませんが、エフェクトとかつけたらそれっぽくなるのではと思います
今回はやらなかったんですが、破片にランダムな回転をかけたりするのもいいかもしれません
意見や感想があればツイッター（ https://x.com/bleibiaccount ）のほうにお願いします
ありがとうございました
![創造と破壊.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985624/3f5fc13b-d0ff-3886-5744-6231129541d9.gif)