On this page |
概要 ¶
Houdiniでは、VOPを使って マテリアル (オブジェクトのレンダリングのルックを制御するサーフェスシェーダとディスプレイスメントシェーダの組み合わせ)を構築します。 Houdiniのシェーダ構築ワークフローは、VOPを繋げてシェーダプログラムを構築する手法を基本としています。
VEXを使用すればテキストコードでシェーダを記述することができますが、VOPを使ってシェーダを構築する方が簡単で楽しいです。
Houdiniには、シェーダ構築に利用できる便利なシェーディングVOPがたくさんあります。
⇥ Tabメニューの Shaders カテゴリにあるハイレベルPrincipled Shaderには、あなたが求めているルックの99%を再現するのに必要なすべてが含まれています。
ハイレベルノードの基本機能をパッケージ化したVOPも存在します。例えば、Principled Shader Coreには、Principled Shaderの基本機能が含まれており、(事前に組み込まれたテクスチャUIなどの)“便利”機能が排除されています。これらを使用して、万能シェーダの機能に独自のUIを追加したり、万能シェーダをレイヤーマテリアルのレイヤーとして使用することができます。
あまり労力をかけずにカスタムシェーダを構築できるように、もっと多くの基本BSDFを生成するノードが存在します。
またVOPネットワークには、あなたのプログラミング言語の能力を全て活かせるほどの多くのローレベルVOPが含まれています。 例えば、数学的な処理やノイズの生成など、あなたがシェーダネットワークでやりたい事ができます。これらのVOPは、プログラム的にハイレベルシェーダの入力を生成するのに役立つことが多いです。
Houdiniにおけるマテリアルの動作に関する詳細は、以下のシェーダ出力を理解するを参照してください。
Masterclass ¶
独自のマテリアルを構築する前に ¶
独自のマテリアルを構築するのは面白くて、Mantraでのシェーディングの動作を理解するのに役立ち、一風変わったエフェクトや幻想的なエフェクトを要する時に必要になることがあります。
とはいえ、ほとんどの場合、Principled Shaderによって、あなたが求めるリアルなルックを再現することができます。 独自のシェーダを構築する必要があると判断する前に、そのシェーダのたくさんある機能とコントロールを調べてみると良いでしょう。 Principled Shaderを使った既製マテリアルに関しては、Material Paletteをチェックしてください。
Material VOPネットワーク ¶
Houdiniには、マテリアルを作成/扱うためのデフォルトネットワーク/mat
があります。ネットワークエディタのメニューにある Go ▸ Materials を選択することで、このネットワークに行くことができます。
他のネットワーク内にMaterial Networkサブネットを手動で作成することもできます。このサブネットによって、デジタルアセット内にマテリアルをパッケージ化することができます。 例えばキャラクタアセットで、そのアセットのネットワーク内にキャラクタのマテリアルを含めることができます。
Materialネットワーク内では、シェーディングVOPを配置して、それらを接続することで、ゼロからシェーダネットワークを構築することができます。 Materialネットワークでは、複数のシェーダツリーとハイレベルシェーダノードを混在させることができます。
ノードの Materialフラグを有効にすることで、そのノードをMaterial Galleryやマテリアル選択で表示させることができます。
3D Scene View内またはRender View内のオブジェクト上にVOPをドラッグすることで、たいていのVOPがそのオブジェクトにマテリアルとして割り当てることができます。
これは、/mat
レベルで物事を試したり、デバッグ時に中間ステージでのシェーダネットワークの出力を確認するのに非常に便利です。
Material Builder以外のVOPを割り当てる時、シーンの背後でHoudiniはそのノードとその上流のノードから一時的なシェーダを構築し、シェーディングで使用するべき出力がどれなのかを賢く推測しようとします。 例えば、そのノードにLayer出力があれば、Houdiniはその出力を使用します。もし浮動小数点の出力しか持たないローレベルVOPだった場合、Houdiniは、そのノードをグレースケールのカラーとして扱います。
Note
Materialネットワーク(例えばmat
)内からでしかVOPを割り当てることができません。他のネットワークタイプ(Material Builderを含む)からVOPを割り当てることはできません。
/mat
レベルでシェーダツリーを構築するのは、プロトタイプや試行錯誤には良いです。しかしながら、マテリアルをちゃんと使用する時は、Material Builderノード内にMaterialネットワークを配置する方が良い考えです。
もう既に“緩い”シェーダツリーを組んでしまっていても、ネットワークエディタでそれらのノードを選択して、 Edit ▸ Collapse Selected into Material を使用すれば、Material Builderノードに格納することができます。 また、Material Builderノードから始めて、その中に入って、そのネットワークを構築することができます。
シェーダをMaterial Builderの中に格納するメリットがいくつかあります:
-
パラメータと入力をプロモートすることで、Material Builderノード上に独自のインターフェースを作成することができます。
-
再利用できるようにMaterial Builderノードをデジタルアセットに変換することができます。
-
/mat
を綺麗な状態に保つことができます。
カスタムマテリアルをレイヤー化したい場合は、Material Builderの出力をレイヤーにすることができます
-
シェーダが生成したコンポーネント(例えば、BSDF)から
ShaderLayer
構造体を構築するために、Material Builderのネットワーク内でLayer Packノードを使用します。 -
Parameterノードを追加します。Parameterノードで、その出力を表現するために名前とラベル(例えば、
layer
)を設定します。 Type を“Struct”に設定してから、サブタイプを“ShaderLayer”に設定します。 Export を“When Input is Connected”に設定します。 -
Layer Packノードの出力をParameterノードの入力に接続します。
これで、親のMaterial Builderノードにlayer出力が追加されました。
出力の生成 ¶
基本的にカスタムシェーダは、VOPノードを使用して基本マテリアルなどのマテリアルの特性を計算させることが多いです。 そして、そのカラーをPrincipled Shader Coreなどのハイレベルノード(またはBSDFを生成する他のノード)に接続して、粗さや反射率などのコントロールといった物理特性を自動的に取得してBSDFを生成することができます。
一般的には、マテリアルのサーフェスカラーはBSDF(F
)出力の形式で生成するべきです。
とはいえ、レンダリングエンジンが変われば、マテリアルネットワークの出力も変更する必要があります:
-
PBR(物理ベースレンダリング)では、BSDF(
F
)出力が必要です。 -
従来のレイトレースでは、シェーダ内のライティング寄与を計算したその最終サーフェスカラー(
Cf
)出力が必要です。
F
を生成し、さらにそのF
(またはlayer
)を受け取って最終サーフェスカラーを計算するCompute Lighting VOPを接続することで、どちらのレンダリングエンジンでも動作するシェーダを簡単に作成することができます。
そして、元のF
とCompute LightingのCf
の両方を出力ノードに接続します:
Note
各レンダリングエンジンは、それに必要なシェーディング出力だけを“クック”します。そのため、PBRを使ってレンダリングすると、そのCompute Lightingノードはクックされません。
Material Builderをデジタルアセットに変換する方法 ¶
Material Builderネットワークは、セットアップが簡単であり、デジタルアセットのバージョン管理といった余計な作業をすることがなくて柔軟性があります。 とはいえ、そのままでマテリアルネットワークを使用した場合、バリエーションを作成するためにそのネットワークをコピーしていくと、コンパイル時間が増えて、もっと多くのメモリを必要とします。
Material Builderネットワークをデジタルアセットに変換した場合、新しいマテリアルのインスタンスを作成することができ、各インスタンスのパラメータを編集してバリエーションを作成することができます。 Materialネットワークのコピーではそのまま複製されるのに対し、デジタルアセットのコピーは複製ではなくインスタンスになります。
また、アーティスト/スタジオ間でマテリアルアセットを共有することができ、Houdiniのアセット管理機能を小することでバージョンをメンテナンスすることができます。
To... | Do this |
---|---|
Material Shader Builderをデジタルアセットに変換する |
Material Builderノードを右クリックして、 Create Digital Asset を選択します。デジタルアセットの保存先の情報を入力して、 Accept をクリックします。 このフィールドの入力の方法は、デジタルアセットの作成を参照してください。 一度ネットワークをデジタルアセットに変換してしまえば、Materialネットワーク(例えば、 |
レイヤー出力を独自マテリアルに追加する方法 ¶
マテリアルを組み合わせることで、新しくブレンドされたルックを作成することができます(詳細は、マテリアルのレイヤー化を参照してください)。 独自マテリアルをレイヤー化したい場合は、現在のところ、手動でレイヤー出力をマテリアルノードに追加する必要があります。
-
マテリアルネットワーク内で、Layer Struct(レイヤー構造体)を生成します。
BRDFを生成するノードには既に
layer
出力を持っていることがあります。持っていなければ、Layer Pack VOPを使用することで、F
出力などの部分からレイヤー構造体を作成することができます。 -
2つ のParameter VOPsを作成します。
-
両方のノードに対して、 Name を同じ値:
layer
に設定します。 -
両方のノードに対して、 Type を“Struct”に設定し、 Use own export context を有効にし、 Export を“Always”に設定します。
-
片方のノードに対して、 Export in context を
surface
に設定します。もう片方のノードに対して、 Export in context をdisplace
に設定します。
-
-
layer
出力をこれら2つのParameterノードの入力に接続します。
これら2つのparameter VOPsが親マテリアルの単一のlayer
出力に結合されます。
同じ名前の2つのExportは干渉しません。その理由は、 Use own export context を有効にしたことで、それぞれのシェーディングコンテキスト(surface
またはdisplace
)に対してコードを生成すると、そのコンテキストのExportのみが“アクティブ”になるからです。“下流”のVOPsは、そのシェーダタイプに基づいて適切なレイヤー情報を選択します。これは、Mantraのアーキテクチャ上の問題を回避するために必要であり、実際にHoudiniではマテリアルを別々のシェーダにコンパイルしています。
ディスプレイスメントを追加する方法 ¶
マテリアルにディスプレイスメントを追加する方法が2つあります:
-
Principled Shaderマテリアルにはディスプレイスメント用の入力(サーフェス法線沿いの浮動小数点変位の
disp
や3D変位ベクトルのvistp
)があります。ディスプレイスメント値を計算するノード(例えば、Cavities VOP)を作成して、それらのノードをマテリアルのディスプレイスメント入力に接続することができます。Principled Shaderに対しては、そのノードの Displacement タブの Use input displacement パラメータを有効にする必要があることに注意してください。これは、
/mat
レベルでディスプレイスメントシェーダを試すのにも非常に役立ちます。ただ単に/mat
内にPrincipled Shaderマテリアルノードを配置して、それをジオメトリに割り当て、 Use input displacement を有効にします。次に、ノードをディスプレイスメント入力に接続することで、レンダビュー内でそのサーフェス上での効果を確認することができます。Note
/mat
レベルで“緩い”ネットワークを構築している場合、Houdiniがそのネットワークからマテリアルを生成する際に、Houdiniはその繋がっているノードからDisplacement Boundsプロパティを探し出して、見つかればそのプロパティをマテリアルに追加します。これは、この特別な処理をするための唯一のプロパティです。これによって、ディスプレイスメント付きのマテリアルをレイヤー化することができます。 -
Material Builderネットワーク内では、ディスプレイスメント値を計算するノード(例えば、Cavities VOP)を作成して、それらのノードをディスプレイスメントOutputノードの
N
入力(3D変位ベクトル)に接続することができます。Tip
サーフェス法線沿い変位させたい浮動小数点距離があれば、その距離とディスプレイスメントグローバルノードの法線(
N
)出力を乗算することで、変位ベクトルを取得することができます。
レンダープロパティをマテリアルの一部として割り当てる方法 ¶
シーン内にレンダリングプロパティを設定する方法が3つあります:
-
オブジェクト、カメラ、マテリアルなどのノード上にSpareパラメータとしてプロパティを追加する。
-
マテリアルスタイルシートにプロパティを割り当てる。
-
Properties VOPを使って、マテリアルネットワークの一部としてプロパティを割り当てる。
Material Builderノードにレンダープロパティを追加すると、そのレンダープロパティがマテリアルのインターフェースの一部になります。 マテリアルネットワーク内部にプロパティを割り当ててしまうと、それらのパラメータをプロモートさせない限り、マテリアルのインターフェースの一部になりません。 基本的には、エンドユーザがマテリアルを変更する必要がないようにProperties VOPを使用します。
To... | Do this |
---|---|
マテリアルにレンダープロパティを追加する |
オブジェクトにマテリアルを割り当てると、そのオブジェクトにもレンダープロパティが適用されます。 |
Note
異なるレベルにおけるプロパティの継承の順番を忘れないでください。例えば、マテリアルにRender Polygons as Subdivisionプロパティを追加して、そのマテリアルが適用されたオブジェクトすべてをサブディビジョン化したとします。しかし、デフォルトでは、すべてのGometryオブジェクトノードには既にRender Polygons as Subdivisionプロパティがあります。このプロパティは、マテリアルのそのプロパティ値を上書きします。そのオブジェクトがマテリアルからそのプロパティ値を取得するようにさせるには、まず最初にそのオブジェクトからそのプロパティ値を削除する必要があります。
シェーダ出力を理解する ¶
昔、Mantraは、サーフェスに対してサーフェスカラーやディスプレイスメント(さらにはfogシェーダなどの現在ではほぼ時代遅れになったタイプのシェーダ)を含む異なるシェーダを受け入れていました。 そして、複数のシェーダを気にすることなく簡単にサーフェスにルックを割り当てることができるようにするために、私たちは、同じネットワーク内に複数のシェーダタイプのノードチェーンを含めることができる マテリアル を導入しました。
マテリアルは、サーフェスシェーダ、ディスプレイスメントシェーダ、レンダープロパティをカプセル化することができます。 サーフェスシェーダとディスプレイスメントシェーダを表現したノードチェーンは、Outputノードに接続します(Outputノード上のパラメータは、それらの入力が作成するシェーダの種類を制御します)。 そして、Collect VOPは、Outputノードのシェーダ出力をマテリアルに結合します。この設計によって、シェーディングのルック(サーフェスカラー、光沢など)とオプションのディスプレイスメントのルック(例えば、肌の溝)を簡単に一枚のマテリアルに結合することができます。Outputノードから出力されている“shader”接続は、VOPネットワーク内の他の接続と同様のVEXデータを表現しているわけではありません。 この接続は、そのシェーダを最終マテリアルにどのように寄与させるのかを示したメタデータを表現しています。
(Material BuilderサブネットまたはMaterial Builderベースのアセットの中では、Output VOPsとCollect VOPがネットワークの最後にあります。/mat
レベルの“緩い”マテリアルに関しては、Houdiniがノードチェーンをマテリアルに変換する時にその終了ノードが存在しなければ、Houdiniがあなたの代わりに自動的に終了ノードを追加します。)
Collect VOPは、Houdiがコンパイルに必要とするノードを追跡しやすくするためにあります(Collect VOPから接続を遡ってノードを追跡することができます)。 また、異なる実装のOutputノードとCollectノードの間にSwitch VOPを挿入することで、シェーダの実装をプログラム的に切り替えることができます(これを必要とするケースはあまりありませんが)。
以上のことから、2つの要素:シェーダ(サーフェスカラーやディスプレイスメントを計算するためのプログラム)とマテリアル(カラー、ディスプレイスメント、プロパティのシェーダ用のコンテナ)があることがわかりました。 しかし、ユーザがマテリアルを混在させて別々のルックをブレンドしたり上に重ねたりしたいです。理論的には、 シェーダ を混合材料として使用することができたのですが、混在させるシェーダを別々に評価して、その計算されたカラー値を合成させるにはあまりにも処理が重すぎました。代わりに、BRDFを混在させたほうが処理が軽く、重い処理のライティングの評価も一回で済みます。 マテリアルのレベルで混在させることができたのですが、マテリアルコンテナでは、混在させるのに非常に手間がかかり、追加情報を扱うのも遅くなります。 そのため、3つ目の要素として レイヤー構造体 を追加しました。この構造体には、サーフェスシェーディングとディスプレイスメントに関する混在可能な情報を含んでいます。
レイヤー は、BRDFと他のデータをパッケージ化して、混在可能なサーフェスシェーダを表現します。 それでも、この混在可能な表現は、(Outputノードで表現された)Compute Lightingステージを通過させて、シェーディングで使用される最終結果にする必要があります。 (レイヤーは、Mantraがレンダリングで使用する本当の最終シェーダを表現しているOutputノードであることを忘れないでください。) 混在ができるようにマテリアルノードにレイヤー出力を持たせるかどうかは任意です。 Houdiniに同梱されているすべての既製マテリアルにはレイヤー出力が備わっています(独自マテリアルにレイヤー出力を追加することで、その独自マテリアルを混在可能にすることもできます)。 マテリアルのレイヤー出力をLayer Mix VOPに接続することで、それらのマテリアルをレイヤー化することができます(詳細は、マテリアルのレイヤー化を参照してください)。
(このあたりのHoudiniは、新しいバージョンのHoudiniがリリースされる度に改良されていく予定です。将来のバージョンのHoudiniでは、おそらく過去の入り組んだ問題を解決したレイヤー中心のわかりやすいワークフローになることでしょう。)
ヒントとメモ ¶
-
現在の位置や法線などのグローバル変数にアクセスする必要がある場合は、(
/mat
レベル、または折り畳まれたMaterial Builder内で)Global Variables VOPを追加することができます。 -
古いバージョンのHoudiniでは、SHOPと呼ばれる別のネットワークタイプがありました。マテリアルは、そのSHOPレベルで割り当てられ、そのSHOPの中でVOPネットワークを使って構築されていました。Houdini 16以降では、このような相反する二面性は存在せず、すべてのシェーディングネットワークはVOPネットワークで処理するようになりました。
この以前のシステムから進化した現在のワークフローでは、シェーディングシステムというよりもMantraで動作させるために、レンダラーを完全にゼロから書き直す必要がありました。 これが原因で、いくつか問題を解決する仕組みがあります。 例えば、Mantraではシェーダが特定のグローバル変数を出力する必要があるのに、レイヤー構造体の扱い方を知らないので、Material Builder(他のVOPを割り当てる時はシーンの背後で)内でHoudiniはレイヤー構造体のコンポーネントを分解するためのノードを追加します。