🐼

[UE5][Houdini][習作] Houdiniで頂点に仕込んだ情報を元に、UEのマテリアルで面の押し出しアニメをしてみました

2025/02/09に公開

HoudiniでSOPやらVEXやら色々学んだので、Houdini側でモデルの頂点に情報を仕込んで、その情報を元に、UEのマテリアルでWorldPositionOffsetによって面の押し出しアニメをしてみました。

デモムービー

こちらが作成したもののデモムービーになります。
https://www.youtube.com/watch?v=s91xYXiVlCw

解説

[Houdini側] 基本形の作成

まずは、Shpereの面上をヘキサグリッドにして、各面を少し押し出します。

これを基本形として、頂点に必要な情報を仕込んでいきます。

[Houdini側] 仕込み情報1:押し出す面の頂点か否か

すべての面を押し出したいわけではありません。押し出したい面の頂点とそうでない頂点を識別するために、押し出したい面に関わる頂点には「1」を、それ以外の頂点には「0」を割り当てたAttributeを作成します。

PolyExtrudeノードで押し出した際に、押し出し面をグループ化できるので、まずは面、すなわちPmrimitiveにAttributeを作成します。そこから、AttributePpromoteノードなどを駆使して、そのPmrimitiveに関わるVertexにAttributeを移します。結果的に↓のようになります。

[Houdini側] 仕込み情報2:平均押し出し方向ベクトル

面を押し出すときは、隣接する面ごとに段差をつけたいので、押し出し面に関わる各頂点には、同一の平均押し出し方向ベクトルをAttributeとして仕込んでおきます。平均押し出し方向ベクトルは、Sphereの中心から各頂点の重心位置へ向かう単位ベクトルとします。

仕込みの対象となるVertexは先程と同じです。先程と同様に、押し出し面のグループやAttributePpromoteノードなどを駆使して、対象となるVertexに平均押し出し方向ベクトルを仕込みます。結果的に↓のようになります。(Visualizationで可視化しています。)

ここで1つ重要なポイントがあります。
Attributeはそのmetadataの種類によってTransformのかかり方が変わります。
平均押し出し方向ベクトルはTransform(Rotate、Scaleのみ)がかかってほしいものですので、metadataは「vector」にしておきます。
Attributeのmetadataについてはこちらのページでまとめましたので、ご興味のある方はご覧ください。
https://zenn.dev/h_sasaki/articles/dca28824130d62

[Houdini側] 仕込み情報をUVに割り当てる

仕込み情報1,2はUEのマテリアル側で参照したい情報になりますので、これらをUVに割り当てます。仕込み情報1は[1-1loat]、2は[3-Float]ですので、今回はuv3, uv4の2つを使います。

  • 仕込み情報2:平均押し出し方向ベクトル
    • uv3.x、uv3.y、uv4.x、 の3つを使用。
  • 仕込み情報1:押し出す面の頂点か否か
    • uv4.y、 の1つを使用。

ここで1つハマりポイントがありました。
Houdini側でUVに割り当てた値が、UE側ではそのUVのV値がどうやらOneMinus(1-x)された値になってしまうようです。このことについては↓のページでまとめましたので、ご興味のある方はご覧ください。
https://zenn.dev/h_sasaki/articles/cfe48215166be6

ハマりポイントを踏まえ、ここでは V値のほうはあらかじめOneMinus(1-x) しておきます。

@uv3.x = v@nAveP.x; // 平均押し出し方向ベクトル(x)
@uv3.y = 1 - v@nAveP.y; // 平均押し出し方向ベクトル(y)
@uv4.x = v@nAveP.z; // 平均押し出し方向ベクトル(z)

@uv4.y = 1 - @ExtrudeFront; // 押し出す面の頂点か否か(0or1)

Houdini側の作業はここまでで、以上のモデルをFBXで書き出します。

[UE側] FBXをインポートする

書き出したFBXをUEにインポートします。
その際、UniformScaleは100にしておきます。

[UE側] マテリアルを作成する

重要なポイントは、Houdini側でUVに仕込んだ情報を取り出すところになります。

「押し出す面の頂点か否か」の情報

Houdini側でuv4.yに割り当てたので、UEマテリアルでは [3].G に該当します。(ややこしいですが、インデックス番号のズレに注意します。)
[3]のGの値が[0or1]になっています。

「平均押し出し方向ベクトル」の情報

こちらはuv3.x、uv3.y、uv4.xに割り当てたので、UEマテリアルではそれぞれ [2].R、[2].G、[3].R に該当します。
[2].R、[2].G、[3].Rの3つをAppendして、「平均押し出し方向ベクトル」を復元してあげます。
注意点として、HoudiniとUEの座標系の違いから、YとZを入れ替えてあげる必要があります。なのでここでは [2].GをZに、[3].RをYに しています。

押し出し量の計算

「平均押し出し方向ベクトル」と任意の方向ベクトルとを内積にかけて、押し出し量を計算します

そもそも「平均押し出し方向ベクトル」を用意したのもこのときのためで、これがなければ隣接する面ごとに段差をつけることができず、滑らかな山なりに押し出されてしまいます
滑らかな山なりに押し出された場合

「平均押し出し方向ベクトル」を用いて隣接する面ごとに段差をつけて押し出した場合

また、押し出し量に「押し出す面の頂点か否か」の[0or1]をかけて、そもそも押し出さない頂点においては押し出し量が0になるようにしてあげます。

マテリアル全体図と部分拡大図

上記の仕込み情報と操作したいパラメータを絡めて表現したいロジックを組んでいきます。こちらは全体図と部分拡大図を載せておきます。

Discussion