🦍

[UE5][Tips] マテリアルでメッシュの頂点を動かしてオブジェクトを回転させてみる

2025/01/13に公開

マテリアルエディタのメインマテリアルノードにある「World Position Offset」というピンを使うことで、メッシュの頂点を動かすことができます。これを使って、オブジェクトをYaw回転させてみます。

もちろん、Blueprintでも回転させることはできますが、マテリアルで行えればアートセクションだけで作業が完結でき、プログラマの手を煩わせなくて済みます。また、CPUリソースを節約してGPUに処理させることができるという利点もあります。

↓のGIF動画が今回作成したマテリアルをオブジェクトに適用した結果になります。
Yaw回転するマテリアルを適用したCubeとSphere

マテリアルノード全体図

こちらが今回作成したマテリアルのノードの全体図です。
大きく分けて、頂点を動かす「World Position Offset」のフェーズと、頂点の持つ法線を再計算する「Normal」のフェーズがあります。

World Position Offset フェーズ

↓のように「World Position Offset」ピンに繋がっているノード群が「オブジェクトのYaw回転」に関係しているものです。

それぞれノードの意味は画像中のコメント通りですが、注意点としては「RotateAboutAxis」ノードは回転させた後の位置との差分を返す、ということです。「World Position Offset」ピンはその名の通り「ワールド空間における位置の移動分(差分)」を入力するところなので、この場合は「RotateAboutAxis」ノードの出力ピンをそのまま繋いであげて大丈夫です。


一応、これだけでオブジェクトはYaw回転するのですが、結果を見てみると陰影が何だかおかしいことが確認できます。
回転しているが陰影がおかしい様子
これは、前述までで頂点を動かしましたが、頂点の持つ法線ベクトルはまだそのままであり、頂点の位置と法線ベクトルの関係がチグハグになってしまっているためです。頂点を動かしたら、併せて法線ベクトルも再計算してあげる必要があります。そちらは「Normal」フェーズで行います。

Normal フェーズ

↓のように「Normal」ピンに繋がっているノード群が「法線ベクトルの再計算」に関係しているものです。

基本的には、頂点の回転移動と同様に、法線ベクトルを回転させてあげれば良いのですが、いくつかの注意点があります。(※「垂直軸」と「回転角」は頂点の回転移動と同様です)

注意点1:PivotPointピンへの入力は(0,0,0)にする

位置と違い、ベクトルの回転の場合は「RotateAboutAxis」ノードの「PivotPoint」ピンへの入力は(0,0,0)にする必要があります。本来、ベクトルの回転に基点は無用であり、逆に(0,0,0)以外を入力してしまうと誤った結果となってしまいますので注意が必要です。

注意点2:Normalピンに必要なのは差分ではなく法線ベクトルそのもの

「World Position Offset ピンには差分を入力する」と前述しましたが、一方、「Normal」ピンのほうは差分ではなく法線ベクトルそのものである必要があります。しかし、「RotateAboutAxis」ノードはあくまで差分を返すので、出てきた差分ともとの法線ベクトルを合算することで新たな法線ベクトルを算出します
また、「Normal」ピンへ入力する法線ベクトルは正規化されている必要がありますので、合算した上で「Normalize」ノードに繋ぎます。

注意点3:Normalピンに入力する法線ベクトルはTangent空間のものでなければならない

ここはそういうものとして、「TransformVector」ノードを使ってベクトルをTangent空間に変換します。これ以前に算出した法線ベクトルはワールド空間のものなので、「TransformVector」ノードの詳細パネルにある設定のSourceは「World Space」に、Destinationは「Tangent Space」にします。

「TransformVector」ノードの詳細パネル


注意点は以上になります。
これで、法線の再計算も正しく行われ、冒頭のGIF動画のような正しいシェーディングの結果が得られます。

追加の注意点

回転するマテリアルを適用したオブジェクトをレベルに配置するときにも気を付けることがあります。
そちらについては↓のページで解説しております。
https://zenn.dev/h_sasaki/articles/d3a4c2e1f2bbc7

Discussion