記事の目次

    Volumeを変形してディテールを追加する方法を紹介します。

    TEXT_秋元純一 / Junichi Akimoto(トランジスタ・スタジオ/ディレクター)
    日本でも指折りのHoudini アーティスト。
    手がけてきた作品は数々の賞を受賞している。
    代表作に、HIDETAKE TAKAYAMA『Express feat. Silla(mum)』など。
    www.transistorstudio.co.jp
    blog.junichiakimoto.com


    EDIT_小村仁美 / Hitomi Komura(CGWORLD)

    VolumeでもVOP

    VDBが登場してから、Volumeのディテールを追加することが非常に手軽になりました。これまでのVolumeは処理が重く、ディテールを追加したり変更したりすることはコストが高いものでした。近年ではOpenVDBの登場によりハイディテール化がしやすく、これまでは諦めていた解像度でも変更を加えることができるようになりました。

    今回は、VDBに対してVOPを使ってディテールを加えるためのアプローチを解説していきたいと思います。メインとなるフローは、VOPを使ったものになりますが、そのためのSOPのフローも重要です。今回作成したVolumeはシミュレーションのためのソースとして使用することもできます。また、フローのベースの考え方として、Pyroのソース作成フローを参考にしています。これは、PointをベースにしてVolumeに変換する流れにすることでより複雑な制御の下地を作ることができるためです。今回のフローを活用すれば、任意な形状の雲などを作成することも容易になります。

    今回のHoudiniプロジェクトデータはこちら

    01 Base VDB Build

    まず初めに、File SOP【A】でVolumeにしたいベースの形状を読み込みます【1】。これに対し、Point from Volume SOP【B】を使って形状の内部にPointを作成します。そのPointに対して、VOP【C】を使って色情報を作成します【2】。VOPではNoiseの輝度を使った色付けを行なっています【D】


    次に、Pointに対してWrangle SOP【E】を使って"pscale"と"density"のアトリビュートを作成します。"pscale"は、Point from VolumeのParticle Separationの倍のサイズにします【3】。それからVolume Rasterize Attribute SOP【F】を使って、Pointのもっているアトリビュート【4】をVolumeに変換します【5】。そのとき、Voxel SizeはPoint from VolumeのParticle Separationと同等の値にします【6】。これによって、PointからVDBを作成することができました。

    通常、PolygonからVDBに変換する際は、VDB from Polygons SOPを使用しますし、その方が無駄がないのですが、今回は、Pointに対して色情報をもたせたかったことと、このフローには入れ込んでいませんが、"density"に対してNoiseを加えたりすることが容易になるため、このような流れを採用しています。

    02 Deform VDB

    Volumeを変形させる準備を整えます。まず、Convert VDB SOP【G】を使ってdensityをPolygonに変換します【7】。このPolygonをVDB from Polygon SOP【H】を使ってSDFに変換しますが、この際は、元々のVolumeをReferenceして変換すれば、Voxelのサイズなどを合わせることができます【8】

    また、その際にBandのセッティングをします【9】。これは、変形に耐えるために、余分なVoxelをもたせるためのセッティングになります。次に、このSDFをVDB Smooth SDF【I】を使ってなめらかにします【10】

    続いて、VDB Active SOP【J】を使って、densityとCdのコンテナを拡張します【11】。これは、Voxel to Expand【12】を用いて、SDFと同等に、変化に耐えうる余白を作るものです。このdensityとCd、SDFをそれぞれMergeして準備は完了です。

    続いて、Volumeを変形させてディテールを追加します。この変形にはVolume VOP【K】を用います。ディテールの生成には、2つのNoiseを用います。まず、Anti-Aliased Flow Noise VOPを使ったNoise【L】を作り、それをPositionに加算します。次に、For Loop内にTurbulent Noise VOPを用いたNoiseを作ります【M】。この流れは、最初のNoiseでPositionにNoiseをAdvect(空間を歪ませる)して、その空間からNoiseを作り出すことで、さらに複雑なNoiseを生成できるしくみです。また、For Loopの中にNoiseを入れることで、いくつもNoiseを重ねたような複雑さをさらに追加できます。


    それから、Volume Gradient VOP【N】を使って、SDFを読み込みます。このSDFの距離データに対して、作成したNoiseの値をかけ合わせます。さらに、必要であればUp Vectorを基に内積値を取り、Noiseを足したい方向だけを抜き出すようなしくみも作り出せます【O】。これらの値を基に、元々のPositionに対してNoiseを足し、最終的にVolume Sample VOP【P】を使ってdensityに返します。Cdの場合はVolume Sample Vector VOP【Q】を使用します。これでディテールを追加できました【13】。ディテールは、複数のVolume VOPを用いて、最終的にVDB Combine SOP【R】でそれぞれのVDBを合わせても良いでしょう。


    最終的にSDFは不要なので削除します【S】。また、不要なVoxelをVDB Active SOP【T】のDeactiveを使って削除して完了です【14】


    densityだけでなくCdにもディテールを加えた理由は、最終的に出力する際に、densityとCdのFieldに大きく差異があると色情報が上手く乗らないためです【15】。これは必要に応じて、各Volumeに変化を加えましょう。


    03 Operators

    主要ノードを解説します。

    ●Volume Gradient VOP/Volume Sample VOP/Volume Sample Vector VOP

    今回紹介するノードは、Volume Gradient VOP、Volume Sample VOP、Volume Sample Vector VOPの計3つです。これらのノードは、Volumeの情報を取得したり、再度サンプリングしたりするために非常に重要な働きをしてくれます。

    Volume Gradient VOPは、指定したVolumeの勾配を計算します。ここでの勾配とは、ボリューム値が増加する方向を示すベクトルを指します。今回の場合、Noiseの値に対して、勾配をかけ合わせることで、SDFの内外にNoiseを足すことができました。Polygonで言うところの法線が取得できないVolumeの場合、このようなアプローチが必要になります。

    Volume Sample VOPVolume Sample Vector VOPは指定したVolumeをサンプリングするためのノードです。今回の場合は、Noiseで変形されたPositionを基に再度値をサンプリングすることで、ディテールを追加することができました。Volumeの場合、Polygonと扱えるデータに差がありますので、そういったハンディキャップを補うためのVOPノードが多数用意されています。


    • 「Houdini COOKBOOK +ACADEMY」
      Houdiniを基礎から楽しく学ぶオンライン講座

      公開日程:毎週金曜日公開(予定)
      価格:1,200円(税込)
      ※第一回「Houdiniの基本概念とインターフェイス」は無料公開中
      受講対象:Houdiniをこれから学びたい方、Houdiniの勉強で挫折した方など
      cgworld.jp/special/houdinicookbookacademy