On this page |
概要 ¶
Houdiniユーザは、Material Library LOP内部でシェーダVOPノードを使用してUSDシェーダを作成します。
ユーザは、特定のレンダラーで求められるシェーダを表現したVOPノードを作成し、それらのVOPノードのパラメータを設定し、それらのVOPノードを接続して、末端シェーダノード(通常では、これはBRDFシェーダまたはサーフェスシェーダが該当します)で完結するようにシェーダネットワークを形成します。 Collect VOPを使用すれば、レンダラー別にいくつかのサーフェスシェーダを1個のUSDマテリアルにまとめることができます。
Material Library LOPは、パラメータで指定された通りに末端シェーダノードを検索してから、 シェーダトランスレータスクリプトを使用してVOPノード入力チェーンを走査して、呼応するUSDシェーダプリミティブを作成します。
実際に、異なるレンダータッゲットと異なる言語に対応できるようにシェーダトランスレータスクリプトがいくつか用意されていて、それらのスクリプトは$HH/husdplugins/shadertranslators/
に配置されています。
このようなセットアップのおかげで、独自のレンダラー向けに独自のシェーダトランスレータを追加することもできます。
クック中に特定のシェーダVOPノードに対して、Material Library LOPは、そのVOPノードのレンダーマスクに基づいて特定のシェーダトランスレータを選択し、それらのVOPノードをUSDシェーダに変換するタスクをそのシェーダトランスレータに渡します。
デフォルトのシェーダトランスレータは、どのレンダーマスクも受け取り、レンダラー別に多種多様なシェーダVOPsを扱うことができます。 このシェーダトランスレータは、VOPノード上のSpareパラメータを使用してVOPノードからUSDプリミティブへの変換方法に関する決定を指示し、さらにパラメータタグを使用して、ノードパラメータからUSDアトリビュートへの変換精度を上げます。
新しいシェーダHDAの作り方 ¶
Solarisで新しいレンダラーのサポートを追加したい場合、その手順の1つは、ユーザがHoudini内でそのレンダラー用のシェーダネットワークを作成できるように、シェーダVOP一式を用意することです。
シェーダHDAを作成する最も単純な方法は、メインメニューから File ▸ New Asset… を使用することです。 VOPs を選択して、 Network Type を“USD Surface Shader”に設定します。 Accept をクリックすると、そのHDAを設定できるようになり、 Node タブ内で、新しいレンダラーまたは新しいシェーディング言語を特定できるように Render Mask を指定し、TABメニューで利用可能なシェーダのフィルタリングに使用される VopNet Mask を指定します。
次に、 Parameters タブ内で、この特定のシェーダに呼応させたノードパラメータを作成してください。 通常では、ノードパラメータの名前は、シェーダパラメータと同じように名前を付けます。 とはいえ、以下のデフォルトのトランスレータセクションに載せているパラメータタグを使用すれば、パラメータ変換(USDアトリビュートの名前とタイプを含む)を設定することができます。
Note
一般的には、シェーダトランスレータがノード出力の情報に基づいてノードパラメータを作成するので、シェーダ出力パラメータに対してノードパラメータは不要です。 しかし、(例えば、特定の名前またはタイプを指定できるように)シェーダ出力を構成する必要がある場合、 非表示ノードパラメータ(例えば、文字列パラメータ)を作成して、そのパラメータ上にその構成を保存することができます。
その後は、 Input/Output タブ内で、ノード上に接続可能な入力を作成することができます。 既にノードパラメータを作成していれば、 Create/Update Inputs from Parameters ボタンを押すことで、それらのノードパラメータ用の入力を作成することができます。 しかし、 New Input メニューや New Output メニューを使用すれば、任意で入力や出力を追加することができます。
これまでの変更を適用または受け入れた後は、Material Library LOP(または/matコンテキスト)内部でその新しいシェーダノードを作成することができるはずです。
最後の手順として、以下のデフォルトのトランスレータセクションに載せているSpareパラメータを使用すれば、シェーダHDAからUSDプリミティブへの変換をもっと細かくカスタマイズすることができます。
例えば、shader_name
という名前の Shader Name パラメータを追加すれば、USDプリミティブ内に作成されるシェーダIDを制御することができます。
HDA生成をスクリプト化する方法 ¶
メインメニューから手動でHDAを作成する方法はシェーダノードの数が少ない場合には良いのですが、カスタムシェーダが膨大にある場合には実用的ではありません。 そのような場合では、スクリプトを使用してHDA定義を生成する方が便利です。
この処理を容易にするために、HDAライブラリファイルを生成可能なshaderhda.py
というPythonモジュールが用意されています。
この基本的な処理は、何かしらのネイティブ表現からサードパーティ製シェーダに関するソース情報を解析して、それをそのPythonモジュールのShader
クラスに定義されているデータ構造に格納することです。
次に、そのShader
クラスの便利関数(例えば、addHDAToFile()
)のどれかをコールすることで、HDAを作成してファイルに保存することができます。
Houdiniに同梱されているmtlx2hda.py
スクリプトが標準MaterialXシェーダに対してHDAを生成している方法がまさにこれです。
HDAをプログラマブルに作成する方法のヒントと推奨のやり方は、そのスクリプトを参考にすると良いでしょう。
自動生成されるPreviewシェーダ ¶
Material Library LOPには、USD準拠のレンダラーが対応しているユニバーサルレンダーコンテキストをターゲットにした標準のUSD Previewシェーダを自動生成するオプションがあります。 Auto-generate Preview Surface Shaders トグルパラメータを有効にすると、このLOPはシェーダVOPを2個のUSDシェーダに変換します: 1つ目のUSDシェーダは特定のレンダラーをターゲットにし、もう1つ目のUSDシェーダはユニバーサルレンダーコンテキストをターゲットにしています。 その特定のレンダラーは、ネイティブシェーダを使用してシーンを高品質でレンダリングしますが、さらに他のレンダラーはプレビューシェーダの近似計算を使用してシーンを妥当な品質でシェーディングすることができます。
指定したレンダラー固有のシェーダノードに対してプレビューシェーダを生成できるようにするには、そのレンダラー固有のシェーダノードのパラメータにOGL
タグを適切に設定して、そのパラメータとプレビューパラメータのマッピングを指定する必要があります。
例えば、ogl_diff
タグは、そのパラメータがディフューズカラーを表現することを示し、ogl_diff_rough
タグはパラメータをディフューズの粗さ係数としてマークします。
パラメータタグの他のサンプルに関しては、 Principled Shader VOPを参考にすると良いでしょう。
この基本的なタグ処理については、ここで説明されていて、認識されるシェーダパラメータタグの完全リストは、このページに載っています。
しかし、シェーダHDAパラメータにタグを付ける最も簡単な方法は、 Operator Type Properties に進んで、 Parameters タブ内でそのパラメータをクリックしてから、右下コーナーにある Built-in Tags… ボタンを押すことです。
このボタンを押すと、“OpenGL”ツリーブランチ下のOGL
タグをリストしたタグブラウザが開きます。
そこから特定のタグをクリックして“Accept”を押すと、そのパラメータにそのタグを追加することができます。
Note
プレビューシェーダは、$HH/husdplugins/shadertranslators/
内のスクリプトを使用して作成され、独自のプレビュートランスレータを記述することができますが、実際のところ良い感じのシェーダ近似結果を得るのにはパラメータのタグ付けで十分です。
デフォルトのシェーダトランスレータ ¶
上記で説明したとおり、Material Library LOPは、$HH/husdplugins/shadertranslators/
内のデフォルトのシェーダトランスレータを利用して、指定されたVOPシェーダノードに基づいてUSDシェーダプリミティブを作成します。
基本的には、このスクリプトはノードを見て、指定されたノードのプロパティからUSDシェーダを作成してから、そのノードのパラメータ群をループしてそれらのパラメータに対して入力アトリビュートを作成し、次に、入力ノード毎に処理を繰り返します。
Spareパラメータ ¶
USDシェーダプリミティブの作成を指示するために、デフォルトのシェーダトランスレータは、利用可能であればSpareパラメータに基づいて単純な経験則を適用します。
例えば、 Shader Primitive Name (shader_shaderprimname
)は、トランスレータにノード名を使用させるというよりも、USDシェーダプリミティブの名前をユーザ側で明示的に指定することができます。
他の便利なプロパティの組み合わせは、 Shader Name (shader_name
)と Shader Name Kind (shader_namekind
)です。
これらのプロパティには、シェーダを特定するためにUSDプリミティブの Asset または ID のアトリビュート値を指定します。
Note
この“Kind”という用語は、USDのジオメトリ種類の概念とは 関係ありません 。 これは単に名前パラメータをIDまたはアセットアトリビュートとして解釈する方法を示したものです。
最後に触れておきたいSpareプロパティの組み合わせの1つは、 Reference Type (shader_referencetype
)と Base Primitive Path (shader_baseprimpath
)です。
これらのプロパティを使用することで、既存のプリミティブなどのUSDプリミティブ参照を作成するようにノードを設定することができます。
パラメータエディタの Node Properties タブ内にSpareパラメータを追加することができます。このタブ内には、 VOP Properties ▸ Shader という名前のツリープロパティブランチがあります。 利用可能なSpareプロパティの完全リストは、Spareプロパティのページを参照してください。
パラメータタグ ¶
USDシェーダプリミティブアトリビュートをさらに調整するために、デフォルトのシェーダトランスレータは、パラメータタグを見て、そのアトリビュートの名前、タイプ、他の特徴を判断します。
パラメータエディタダイアログを使用してタグをパラメータに追加することができます。 このダイアログのパラメータプロパティペインの右下コーナーにTagテーブルがあります。 そこにある Built-in Tags… アクションボタンを押すと、プリセット値が入ったシェーダパラメータタグを含んだTagブラウザが開きます。
デフォルトのシェーダトランスレータで認識される利用可能なパラメータタグの完全リストを以下に載せています。
sidefx::shader_forceparmval
これを1
に設定すると、そのノードパラメータがデフォルト値であっても強制的にシェーダ入力アトリビュートが作成されます。デフォルト値は0
です。
Note
個々のパラメータにタグを設定することなくこれを制御できるように、シェーダノードに追加可能なshader_skipdefvalparms
Spareパラメータが用意されています。
sidefx::shader_isparm
これを0
に設定すると、そのノードパラメータがシェーダパラメータを表現しないように指定されるので、トランスレータは、そのノードパラメータに対して何もアトリビュートを作成しません。デフォルト値は1
です。
Note
デフォルトの挙動を制御できるように、シェーダノードに追加可能なshader_useallparms
Spareパラメータが用意されています。
sidefx::shader_isparmuniform
これを1
に設定すると、該当するシェーダパラメータが(varyingではなく)uniformであると指定されます。
これは、そのような型修飾子に対応しているシェーダ言語で使用することができ、変換された表現内に正しいvaryingを設定します。デフォルト値は0
です。
sidefx::shader_parmname
そのノードパラメータに呼応したUSDアトリビュート(つまり、シェーダパラメータ)の名前を指定します。デフォルト値は""
です。
sidefx::shader_parmtype
そのノードパラメータに呼応したUSDアトリビュートのタイプ名を指定します。デフォルト値は""
です。
sidefx::shader_parmrendertype
そのノードパラメータに呼応したUSDシェーダ入力アトリビュートのレンダータイプ名を指定します。
シェーダトランスレータは、このレンダータイプを文字列メタデータとしてシェーダの入力アトリビュート上に作成します。デフォルト値は""
です。
sidefx::connector_kind
これは Generic Shader VOP に適用可能で、そのパラメータに、それに呼応する入力コネクタ、呼応する出力コネクタ、それらの両方、またはどちらも持たせないのか決めます。指定可能な値は以下のどれかです:
"none"
そのパラメータは、呼応する入力や出力のどちらのポートも持ちません。
"in"
そのパラメータは、呼応する入力ポートを持ちますが、出力ポートを持ちません。
"out"
そのパラメータは、呼応する出力ポートを持ちますが、入力ポートを持ちません。
"inout"
そのパラメータは、呼応する入力ポートと出力ポートを両方持ちます。
sidefx::connector_type
これは Generic Shader VOP に適用可能で、呼応するノードコネクタポートのVOPタイプを指定します。デフォルト値は""
です。
独自のシェーダトランスレータの作り方 ¶
デフォルトのシェーダトランスレータはたいていの使用場面を網羅していますが、特定のレンダラーまたはシェーディング言語に向けた独自のシェーダトランスレータを作りたい場合があります。 例えば、VOPノードをUSDシェーダプリミティブに適切に変換するために、そのVOPノードに何か特別な処理と独自の制御が必要になる場合があります。
そのような場合では、Pythonコードを記述することで、その変換を制御することができます。
Houdini検索パス(または、設定していればHOUDINI_HUSDPLUGINS_PATH
)のhusdplugins/shadertranslators/
サブディレクトリ内にそのPythonファイルを配置すると、そのPythonファイルにトランスレータオブジェクトを返すusdShaderTranslator()
API関数が含まれていた場合、シェーダ変換フレームワークはそのPythonファイルを取得して、それをトランスレータとして登録します。
返されるトランスレータオブジェクトは、husd/shadertranslator.py
で定義されているShaderTranslator
Pythonクラスと相互交換が可能です。
つまり、ShaderTranslator
で実装されているものと同じシグネチャのすべてのメソッドが実装されます。
このShaderTranslator
クラスには、LOPsがシェーダ変換を実行する際に呼び出すメソッドがいくつか含まれています。
例えば、matchesRenderMask()
メソッドは、指定されたレンダーマスクを持つシェーダをトランスレータが処理するかどうかテストします。
シェーダトランスレータには、与えられたシェーダノードと他の情報から実際にUSDシェーダプリミティブを作成するcreateMaterialShader()
メソッドも用意する必要があります。
独自のシェーダトランスレータを作成する1つの方法は、ShaderTranslator
クラスからカスタムクラスを派生させてから、独自の挙動をするようにいくつかのメソッドをオーバーライドすることです。
Pythonシェーダトランスレータに関する技術的な詳細は、$HH/husdplugins/shadertranslators/default.py
とhusd/shadertranslator.py
の中にあるコードドキュメントを参照してください。
Note
HDKを使用してC++で独自のシェーダトランスレータを作成することも可能です。
HUSDライブラリのHUSD_ShaderTranslatorRegistry
クラスとHUSD_ShaderTranslator
クラスを参照してください。
シェーダ出力の視覚化 ¶
デフォルトのシェーダトランスレータは、シェーダネットワークのデバッグには Visualize VOP を使用することを選択しました。 ホットキーxを使用または手動でそのノードをパターンシェーダノードの出力に接続すると、トランスレータは、その出力をレンダリングするUSDマテリアルを繋ぎます。 これは、 Attribute VOP SOPの中で Visualize VOPを使用するのと同様です。
シェーディング言語が違えばその言語が持つ発光などを構成できる独自の標準(または他の)サーフェスシェーダも異なるので、 Visualize VOPの実際の変換は、シェーディング言語に依存します。 結局のところ、通常の運用では、パターンシェーダ出力が標準シェーダの入力を駆動させます。この標準シェーダはUSDマテリアルの一時的な末端シェーダとして作成されます。例えば、MaterialXの場合、シェーダトランスレータはUniform EDFシェーダとSurfaceシェーダを使用します。
デフォルトのシェーダトランスレータには、視覚化を実行するUSD言語依存のShader Prim(s)を作成して接続するためのcreateUsdVisualizerShader()
APIコールが用意されています。
デバッグ用のシェーダの視覚化を用意するために独自のトランスレータを作成したいのであれば、この関数をオーバーライドすると良いでしょう。
このサンプルに関しては、husdplugins/shadertranslators/mtlx.py
を参考にしてください。
このサンプルは、 ND_UsdPreviewSurface_surfaceshader USDシェーダを作成してセットアップします。