Houdiniでブロック化!

INDEX

はじめに

こんにちは。モノリスソフト テクニカルアーティストの相田です。

今回は、インプットしたジオメトリをもとにプロシージャルにブロックっぽくさせるノードグラフの解説をしていきます。

モジュールの考え方や、ボリューム(特にSDFの考え方)UVの取り扱い座標変換などなど、いろいろと学べることが多いと思います。ぜひHIPを見てみて、写経などやってみてください!

サンプルファイル(monolithtech_block.zip 86.1 KB)はこちらです。

DOWNLOAD

1. ブロックの作成

まず、ブロックを作っていきます。

tech_41_02.jpg

❶ GridSOP のエクスプレッション

Tubeをグリッド上で並べるために GridSOP を使っています。RowColumn の値はそのまま RelativeReferenceですが、Size についてはここで生成されたポイントをもとにコピーをするので、大きさとしては、それぞれ RowColumn から-1の値になります。

tech_41_03.jpg

❷ Subnet 化する意味

HIPを見ると分かりますが、このプロセスは SubnetSOP のなかにまとまっていて、SubnetSOP にパラメータを作って参照しています。なぜこうしているかというと、このブロック作成プロセスは他のプロセスから独立しているからです。

このプロセスは他のプロセスと比べて非常にまとまっているプロセスなので、SubnetSOP にまとめ、パラメータを SubnetSOP から触れるようにすることで、モジュール化をすることができます。

これによって、パラメータを調整することでブロックを簡単に調整することができ、ネットワークも非常にキレイに保つことができます。

tech_41_04.jpg

2. volumeからポイントを生成

ブロックができたので、それをコピーするポイントを生成していきます。

tech_41_05.jpg

❶ transformSOP でスケールをかける意味

ポイントの生成には attribfromvolumeSOP を使っています。

ただし、ブロックのサイズ比が違う場合は以下のような対応が必要です。「ブロックの縦横 =0.008 と高さ =0.0096 の長さが違う 」という場合を考えます。

attribfromvolumeSOPpoint separationの値でポイントを生成します。縦横にあわせて考えると、ポイント間は (X, Y, Z = 0.008, 0.008, 0.008) となり、このままでブロックをコピーすると、

(ブロックの高さ) - (Point Separation の値) 

= 0.0096 - 0.008

= 0.0016

の幅がブロック間で重複してしまいます。

これを修正するために、transformSOP で一時的にスケールをかけているんですね。こうすることで補正後のポイント間は (X, Y, Z = 0.008, 0.0096, 0.008) となり、ブロックのサイズにちょうど合うようになります。

これも座標変換です。こういう操作に慣れてくると、グッと Houdini が楽しくなってくると思います!

tech_41_06.jpg

補正なしだとブロックが重複してしまい、 Z Fight が発生しています。

❷ SDF で内側のポイントを消去

続く attribwrangleSOP では、内側にあるポイントを削除しています。この操作では、SDF を使っています。

SDF とは、Sign Distance Fields の略で、簡単に言うと、ジオメトリの内側と外側を判別するものです。

これをうまく使って、vdbfrompolygonsSOP でジオメトリを SDF 化し、attribwrangleSOP でポイントの位置で SDF をサンプリングし、その値でしきい値を越えたらポイントを削除する、という流れです。

tech_41_07.jpg

SDFを視覚化してみた例。外側に近いポイントは黒く、内側のポイントは白くなっています。

3. テクスチャからポイントカラーを取得

ポイントが生成できたので、ここで uv をもとにテクスチャカラーを取得します。

tech_41_08.jpg

❶ uvを取得するための準備

まず uv を取得する前に、転写元のモデルの uvアトリビュート[ Vertices ] に所属しているので、これを [ Points ] にする必要性があります(転写対象のポイントは vertex を持たないため)。

しかし、attribpromoteSOPuv[ Points ]Promote すると、下図のようにナゾの縞が表れてしまいます。これは、UVアイランドの切れ目 によるものです。

NOTE:

VertexPointsUV ilands の説明はこちらをご参照ください。

tech_41_09.jpg

splituvseamsSOP がオフだとナゾの縞が現れます。

これを回避するために、splituvseamsSOP を使用しています。

splituvseamsSOP によって、UVの切れ目 に沿ってメッシュを split しています。こうすることで縞が発生しなくなります。

ビューポートだけでは分かりませんが、ビューポート右の青四角のアイコンを押すと メッシュの切れ目 を可視化できます。緑四角のアイコンは UVの切れ目 を可視化できます。splituvseamsSOP によって、uvの切れ目 と同じところに メッシュの切れ目 ができていることがわかると思います。

tech_41_10.jpg

青四角をオンにすると、splituvsemsSOP によって青い線が現れるようになります。

NOTE:

ここを理解できるようになると、Houdini力がグッと上がります!

❷ テクスチャカラーを取得

転写元の uv が準備できたので、attribtransferSOP で転写対象のポイントに uv を転写して、attribfrommapSOP でテクスチャカラーを取得します。

attribfrommapSOP では、uvアトリビュート の座標を使って texturemap からカラー情報を取得しています。実はこれも座標変換ですね。

tech_41_11.jpg

Viewportにマウスオーバー → Dキー → Geometry → Display Particles as : Points, PointSize : 15 でこのビューポートにすることができます。

4. 最後の仕上げ

最後にアニメーションを計算し、少しだけポストプロセスな処理をします。

tech_41_12.jpg

❶ アニメーションの計算

この vex は少々複雑なので、詳しくはコード内のコメントを見てみて下さい。ここで計算した progress を使って pscaleアトリビュートPアトリビュート を加工することで、ブロックのコピーでアニメーションしているわけですね。

NOTE:

コピーのアトリビュートについてはこちらが分かりやすいです!

tech_41_13.jpg

❷ ランダムにずらす

これは寄りで見ないと分からないですが、 PアトリビュートのY値 に若干のランダムな値を加えています。

これによってブロックによくある、「若干はまってない」感じを再現しています。

tech_41_14.jpg

まとめ

以上がブロック化ノードグラフの説明です。

このノードグラフはインプットモデルとテクスチャ指定を変えればどんなモデルでもブロック化できるようになっているので、いろいろと差し替えて遊んでみてください!

tech_41_15.jpg

スマートフォンで3Dキャプチャしたモデルをブロック化した例
© Nintendo / MONOLITHSOFT

また、まだいくつか改善案があると思います。今思いついているのは、

  • 色を制限して少ない色数で再現したほうがブロックっぽい
  • 今は1×1ピースのみだが、1×Nピースや2×Nピースのブロックを使いたい
  • アニメーションをもっと豪華にしたい

などがあると思います。思いついた改善案に対して、どう実装するかを考えてみるのも楽しいですね!

執筆者:相田

映像業界を経てモノリスソフトへ入社。 以来、テクニカルアーティストとして主にHoudini関連の業務を担当。 好きな爬虫類はヒルヤモリ。

ABOUT

モノリスソフト開発スタッフが日々取り組んでいる技術研究やノウハウをご紹介

RECRUIT採用情報