見出し画像

マテリアルとBPを使った万華鏡表現

Unreal Engine (UE) Advent Calendar 2022の4日目の記事です。

作ったもの

元ネタ

元ネタは Doctor Strange のVFX

このような表現は一般的にはVATで表現したくなるところですが、VATは制作コストもデータサイズも高いので、もっとお手軽に作る方法を考えました。
※ 一般的にVATは描画コストは低いですが、非圧縮のHDR画像を必要とするのでデータサイズは大きめです。

考え方

一見かなり複雑な動きをしているようですが、よく見ればシンプルな特徴に気が付きます。

わかりやすいようにオブジェクト同士の隙間を広げています
この箇所に注目してみれば原点を中心にミラーしていることがわかります
その2つのセットを 360°/N(繰り返し回数) づつ回転して並べます
それぞれのオブジェクトが扇形の範囲からはみ出さないようにカットします。
これはマテリアルで行います。

オブジェクトを配置する

たくさんのオブジェクトを配置するので、手動で配置する方法のほかに、コンストラクションスクリプトでプロシージャルに配置する方法が考えられます。

今回は手動で配置する場合で解説します。

それぞれのオブジェクトに回転を加えつつ、グローバル座標で360°/Nづつ回転を加えるのは手動では計算が困難なので、SceneRootを使います。
SceneRootでは360°/Nづつのグローバルな回転を行い、メッシュの回転には同じ値を入れます。
同じ値の回転が加わることで、万華鏡のような鏡写しの関係にみえます。

SceneRootを活用して計算を単純化

例えばSceneRootB Mirrorは1個目の回転セットなので、90°回転しつつ、スケールにマイナスを入れます。

この入力が手間…

マテリアルによるオブジェクトのカット

任意の平面でオブジェクトをカットするにはWorldPositionとの内積で計算できます。

しかしこのままでは平面の角度を定義しにくいので、Directionの値をsin(rot)とcos(rot)から求めます。rotは0-1で一周します。

同じ仕組みをもう一つ作って、終端まで角度をずらし、反転してminで和集合をとればピザ型の範囲を取得できます。
rotは0-1で一周するので8つの始端と終端は、1/8(=0.125)の差を設ければいいわけです。
カットしたい場合にはマテリアルをMaskedにしてOpacity Maskに接続してください。

オブジェクトを回転させる

オブジェクトを回転させるには、シンプルにTickでRotationを更新するだけです。
Combine Rotatersを使うと、任意の軸で回転できます。
ちなみにRotaterの値に直接加算する場合、Pitchは90°以上は回転しなくなるため、回転にかなりの制限を受けます。そのためCombine Rotatersのようなクォータニオンの回転を使うのが便利です。

いかがだったでしょうか?
一見複雑な表現でも、法則性さえ見つければかなり簡単に実装できることがわかるかと思います。
ぜひ遊んでみてください。

この記事が気に入ったらサポートをしてみませんか?