Houdini 19.5 Solaris

USDへ書き出す方法

On this page

概要

USDの背景情報、LOPノードがUSDレイヤーを生成する方法については、USDの基本LOPノードについてを参照してください。

LOPネットワークは、USDステージをゼロから、または、トップレベルのUSDファイルから生成し、場合によってはファイルからUSDレイヤーを追加します。 ネットワークの最後では、完了したUSDを書き出すことができます。これには、トップレベルのファイルとレイヤー毎のファイルといった複数ファイルの書き出しを伴うことが多いです。

ディスクから読み込まれたレイヤーは、保存工程では常に変更なしのままになります。とはいっても、LOPノードで生成された匿名レイヤーは、既存のディスク上のレイヤーファイルを上書きすることができます。

How to

  • USDを書き出すメインノードは、USDノードです。このノードは、LOP(LOPネットワークの最後に配置することができます)またはROP(レンダーネットワーク内に配置して、出力したいLOPネットワークを指すことができます)として利用可能です。

    (特別なオプションの詳細は、以下のUSDを書き出す別の方法を参照してください。)

  • USDZファイルを作成したいのであれば、既存のUSDファイル一式から単一の自己完結型のUSDZファイルを作成するUSD Zipノードを使用すると良いでしょう。このファイルは、すべてのレイヤーファイルとそれらのレイヤーファイルで使用されているすべてのテクスチャを含んだアーカイブです。これは、インターネット上で最終USD作品を公開するのに非常に役に立ちますが、このファイルフォーマットには制限があるため、パイプラインでのほとんどの用途には適しません。これは修正するのが面倒で(個々のファイルに展開してから、それぞれ修正してから、再びパッケージ化しなければなりません)、USDZアーカイブ内にボリュームファイルを入れることはできません。

ファイルの出力先

  • USDノードでは、ルートレイヤーのデータを含んだ“トップレベル”のUSDファイルのファイルパス( Output File パラメータ)を指定します。

    このファイルの他にも、このノードは、保存パスメタデータでUSDファイルの出力先が設定されたレイヤーを書き出します。

  • Configure Layer LOPを使用することで、ネットワーク内のレイヤーの保存パスを割り当て/変更することができます。USDを出力する時、そのレイヤーがディスクに書き出されるようになります。

  • SOP Import LOPSOP Create LOPでも、USDを書き出す時に書き出されるジオメトリの保存パスを指定することができます。

  • 保存パスは、HIP($HIP/props/lamp.usd)などのグローバル変数を使用することが多く、絶対パスで指定してください。保存処理時に、デフォルトではUSDノードは、絶対パスをレイヤーファイル間での相対パスに変換する出力プロセッサを使用します。これによって、すべてのレイヤーファイルをある場所から別の場所に移しやすくなります。

  • USDノードの Flush Data After Each Frame パラメータは、各フレームを計算した後にデータをディスクに書き出すかどうかを制御します。 このオプションを使用することで、出力ファイル名または保存パスに時間変化のコンポーネント(例えば、$F)が含まれているかどうに応じて、それぞれ単一タイムサンプルを含んだUSDファイルのシーケンス(例えば、lamp_0001.usdlamp_0002.usdなど)または全フレームのタイムサンプルデータを含んだ単一ファイルを生成することができます。

出力プロセッサ

出力プロセッサは、参照している外部ファイルで使用されているファイルの場所とファイルパス文字列を変更することができるPythonプラグインです。 さらに、出力プロセッサは、保存される直前に各レイヤーファイルに好きなように編集を加えることも可能です。

USDノードは、レイヤーファイル内のファイルパス参照を相対パスに変換するデフォルトの出力プロセッサを使って開始します。

独自の出力プロセッサを記述する方法

  1. $HOUDINI_USER_PREFS_DIR/husdplugins/outputprocessorsという新しいディレクトリを作成します。

    (この例では、私どもはユーザープリファレンスディレクトリ内にこのプラグインを作成していきます。もちろん、Houdiniパス上の任意のディレクトリ下にhusdplugins/outputprocessorsディレクトリを配置しても構いません。)

  2. $HOUDINI_USER_PREFS_DIR/husdplugins/outputprocessors内に、出力プロセッサプラグイン用のPythonファイルを作成します。例:

    $HOUDINI_USER_PREFS_DIR/husdplugins/outputprocessors/outputreview.py
    
  3. Pythonプラグインファイル内で、husd.outputprocessor.OutputProcessorクラスをサブクラスにします。

    このサブクラス内で、固有名を返すname()静的メソッド、出力プロセッサの処理内容(例えば、出力パスを基準にパスを保存)を記述した文字列を返すdisplayName()静的メソッドを実装します。

    import hou
    from husd.outputprocessor import OutputProcessor
    
    class ReviewOutputProcessor(OutputProcessor):
        @staticmethod
        def name():
            return "review"
        @staticmethod
        def displayName():
            return "Manually Review Every Output Path"
    
  4. このファイルの最後に、引数なしで受け取り、コールされる度にクラスを返すusdOutputProcessor()という名前の関数を定義します。

    この関数は、このモジュールを出力プロセッサの実装としてマークし(Houdiniは、この関数を含んだモジュールを検索します)、Houdiniに出力プロセッサオブジェクトのインスタンスの作成方法を示すためにあります。 USD保存処理が開始される度に、出力プロセッサの新しいインスタンスが生成されます。 このインスタンスは、その保存処理の間で使用されます。

    import hou
    from husd.outputprocessor import OutputProcessor
    
    class ReviewOutputProcessor(OutputProcessor):
        @staticmethod
        def name():
            return __class__.__name__
        @staticmethod
        def displayName():
            return "Display the list of output files"
    
    # 以下の記述が必須です: プロセッサインスタンスを返すモジュールレベルの関数
    outputprocessor = ReviewOutputProcessor()
    def usdOutputProcessor():
        return outputprocessor
    
  5. あなたの出力プロセッサを実装できるようにAPIメソッドをオーバーライドします。以下の出力プロセッサAPIを参照してください。

    import hou
    from husd.outputprocessor import OutputProcessor
    
    class ReviewOutputProcessor(OutputProcessor):
        @staticmethod
        def name():
            return "displayoutputfiles"
        @staticmethod
        def displayName():
            return "Display the list of output files"
    
        def processSavePath(self, asset_path, referencing_layer_path, asset_is_layer):
            # アセットパスを絶対パスにします。
            asset_path = hou.text.abspath(asset_path)
    
            # このプロセッサは、ユーザーに手動ですべてのファイルパスを書き換えるように促します。
            # これは単なるサンプルなので、実行しないでください! 面倒くさいことになります!
            return hou.ui.readInput(
                message="Rewrite this output file path if you want",
                initial_contents=asset_path,
                buttons=("OK",),
            )
    
        def processReferencePath(self, asset_path, referencing_layer_path, asset_is_layer):
            # ファイルパスがソースファイルの位置を基準に指すようにします。
            return hou.text.relpath(asset_path, referencing_layer_path)
    
    # 以下の記述が必須です: プロセッサクラスを返すモジュールレベルの関数
    outputprocessor = ReviewOutputProcessor()
    def usdOutputProcessor():
        return ReviewOutputProcessor
    

出力プロセッサメソッドAPI

@staticmethod hidden()bool

このメソッドがTrueを返すと、このプロセッサは、ユーザーに表示される出力プロセッサのリストに含まれません。 デフォルトの実装はFalseを返します。

@staticmethod name()str (必須)

プロセッサの固有名を返します。

Note

必ずサブクラス内でこのメソッドをオーバーライドしてください。 そうしないと、Houdiniがあなたのクラスをインスタンス化しようとした時にNotImplementedError例外が発生します。

@staticmethod displayName()str (必須)

ユーザーに表示される出力プロセッサのリスト内でそのプロセッサについて記述したラベルを返します。

このラベルには、プロセッサの機能について記述してください。例えば、Save Paths Relative to Output Pathです。

Note

必ずサブクラス内でこのメソッドをオーバーライドしてください。 そうしないと、Houdiniがあなたのクラスをインスタンス化しようとした時にNotImplementedError例外が発生します。

@staticmethod parameters()str

このプロセッサがユーザー側で設定できるように表示するパラメータを記述したHoudini“ダイアログスクリプト”を含んだ文字列を返します。

デフォルトの実装は、空っぽのパラメータグループのスクリプトを返すので、 あなたのプロセッサが何もパラメータを必要としないなら、このメソッドをオーバーライドする必要はありません

hou.ParmTemplateオブジェクトを中で使ってhou.ParmTemplateGroupを構築して、hou.ParmTemplateGroup.asDialogScriptから値を返すことで、ダイアログスクリプトを生成することができます。

group = hou.ParmTemplateGroup()
group.append(hou.StringParmTemplate(
    "texturedir",
    "Texture Directory",
    string_type=hou.stringParmType.FileReference
))
return group.asDialogScript()

ここで作成するパラメータの内部名は、必ずレンダーノード上の他のすべてのパラメータ間で固有でなければならないので、 modulename_parmnameのような命名規則を使用するのが良いでしょう(modulenamehusdplugins/outputprocessors下のPythonモジュールの名前です)。

beginSave(self, config_node, config_overrides, lop_node, t)

このプロセッサを使ったレンダーノードがファイルの書き出しを始めた時にコールされます。 この時にパラメータ値(必要な情報に基づいてparameters()で追加されたコンフィグパラメータまたはレンダーノード自体のパラメータのどれか)を読み込む機会が得られます。 このメソッドの基本クラス実装を常にコールしてください。 これによって、処理系メソッドで使用できるように、config_nodelop_nodetのパラメータがそれぞれself.config_nodeself.lop_nodeself.tに格納されます。

config_node

レンダーノードを表現したhou.Nodeオブジェクト。

config_overrides

このノード上に設定可能な値を上書きする際に使用する値のdictOutputProcessor.evalConfigメソッドを使用することで、config_node上のマッチしたパラメータを評価して設定値を照会し、 利用可能であればこの辞書からオーバーライド値を受け入れ、利用不可であれば代替値を使用します。

lop_node

保存されるステージを生成したLOPノードを表現したhou.LopNodeオブジェクト。

t

このノードがレンダリングするタイムラインに沿った時間(秒)を表現した浮動小数点値。 このノードからパラメータ値を読み込む時、そのパラメータがアニメーションしている場合はParm.evalAtTime(t)を使用してください。

processSavePath(self, asset_path, referencing_layer_path, asset_is_layer)str

レンダーノードがアセットを保存するディスク上の場所を決定する必要がある時にコールされます。 asset_pathは、Houdiniが(例えば、USDメタデータまたはHoudiniパラメータから)理解できるファイルパスです。

これは、アセットの保存先となる絶対パスを返してください。 (このメソッドで相対パスを返した場合、そのパスは現行ディレクトリ(os.getcwd())を基準にしたパスになります。おそらくそれはあなたが求めているものではないでしょう)

asset_path

Houdiniで指定されたとおりのアセットのパス。 この文字列は、エクスプレッションと環境変数(例えば$HIP)が既に展開された状態になるので、 他のパスと比較したい場合は、(例えば、os.path.expandvars()hou.text.expandString()を使って)そのパスも展開してください。

referencing_layer_path

このアセットを参照しているレイヤーファイルの処理される保存パス。 このパラメータによって、アセットをシーン内に取り込むレイヤーを基準にそれらのアセットを特定の場所に保存することができます。 これは、ボリュームファイルなどの保存処理中に書き出される非レイヤーファイルで特に役立ちます。

asset_is_layer

このアセットがUSDレイヤーファイルかどうかを示したブール値。 これがFalseの場合、そのアセットは他の何かです(例えば、テクスチャやボリュームのファイル)。

Note

行内の最初のプロセッサのみが、元々Houdiniに存在したかのようにasset_pathを見ます。 行内のそれ以外のすべてのプロセッサに関しては、最初のコールが返した絶対パスを受け取ります。

processReferencePath(self, asset_path, referencing_layer_path, asset_is_layer)str

レンダーノードがアセット(ファイル内のサブレイヤーまたは参照)を指したファイルパスを書き出す必要がある時にコールされます。

asset_path

アセットのパス。 アセットがUSD保存処理の一部として作成されている場合、これは、すべての出力プロセッサを実行した後のアセットの最終保存パスになります。 この値は常にフルパスになります。

referencing_layer_path

アセットの参照を含んだレイヤーファイルの処理された絶対保存場所。 このパスを使用して、パスポインタを相対パスにすることができます(例えば、hou.text.relpath(asset_saved_path, referencing_layer_path))。

asset_is_layer

このアセットがUSDレイヤーファイルかどうかを示したブール値。 これがFalseの場合、そのアセットは他の何かです(例えば、テクスチャやボリュームのファイル)。

processLayer(self, layer)

レイヤーファイルをディスクに書き出す直前にコールされます。 layerパラメータには、編集可能なpxr.Sdf.Layerオブジェクトを渡し、どの方法でも変更することができます。 デフォルトの実装では、レイヤーは変更されません。

このメソッドがレイヤーを変更すればTrue、変更しないならFalseを返します。

スクリプトで出力プロセッサを追加する方法

  • Houdiniは、USDノードインスタンスのenableoutputprocessor_modulename(modulenamehusdplugins/outputprocessors下のPythonモジュールの名前)という名前のSpareチェックボックスパラメータが有効になっていれば、そのノード上の出力プロセッサを使用します。

    例えば、$HOUDINI_USER_PREFS_DIR/husdplugins/outputprocessors/myprocessor.pyで独自のクラスを実装した場合、ノード上にプロセッサをアクティブ化するためのenableoutputprocessor_myprocessorという名前のSpareチェックボックスパラメータを用意する必要があります。

  • これは、ユーザーインターフェース内のプロセッサリストでプロセッサが非表示(上記のhidden()メソッドを参照)になっていたとしても、スクリプトなどで正しいパラメータを作成してそれを有効にすることで、そのプロセッサを有効にすることができることを意味します。

    Spareチェックボックスを無効またはSpareパラメータを削除することで、プロセッサを無効にすることができます。

  • 出力プロセッサが設定用の追加パラメータ(上記のparameters()メソッドを参照)を持っている場合でも、スクリプトでそれらのパラメータを作成して値を設定することができます。

アニメーションを保存する方法

USDレンダーノードの Flush Data After Each Frame パラメータは、各フレームのデータを生成した後にデータを書き出すのかどうかを制御します。 この機能を使用することで、各フレームのデータを含んだファイルを個々に作成したり、制限なくすべてのフレームのタイムサンプルデータを含んだ大きなファイルを作成することができます。

USDレンダーノードの Flush Data After Each Frame を無効にしてフレーム範囲を書き出す時:

  1. このROPは、フレーム毎に、ディスクへの保存の準備をした一連のレイヤーを生成しますが、まだIn-Memoryレイヤーのままです。

  2. USD Stitchを使って、前フレームでクックされたIn-Memoryレイヤーと現在クックされたIn-Memoryレイヤーを結合します。

LOPネットワークが膨大なデータを生成する場合、(USD Stichはフレーム間で同じデータを複製しませんが)これだと即座に大量のメモリを消費してしまいます。

アニメーションUSDを書き出す際にHoudiniでメモリが足りないようであれば、このオプションを有効にすることで、Houdiniが常に単一フレーム分のデータのみをメモリに格納するように制限することができます。 その結果として、ディスクへの書き込み時間が長くなり、最終ファイルサイズはこのオプションを無効にした場合よりも大きくなってしまいます。 しかし、書き出し可能なデータ量は、コンピュータが利用可能なメモリ量に制限されません。

他にも、それぞれ単一タイムサンプルデータを含んだUSDファイルのシーケンスを書き出してから、USD Stitch Clips ROPを使用してUSD Value Clipを生成する方法があります。 この方法は、その巨大なデータセットが存在するシーングラフツリー内に独立したブランチが存在する場合にのみ機能し、このブランチのデータを別のUSDファイルに書き出すことができます。

USDを書き出す他の方法

  • Python(Pythonシェルでインタラクティブに、または、Python Script LOPでプロシージャルに)を使って、個々のファイルに書き出すことができます。

  • ノード上で右クリックして、 LOP Actions サブメニューを開いて、 Inspect flattened stage または Inspect active layer を選択することができます。これらのメニュー項目は、ステージ/レイヤーをusdaコードとして表示するビューアウィンドウを開きます。 このウィンドウからusdaコードをファイルに保存することができます。

Solaris

USD

ジオメトリ

  • SOPをUSDに取り込む方法

    HoudiniがSOPジオメトリをUSDに変換する方法、その工程を制御する方法の詳細。

  • Component Builder

    Component Builderツールは、マテリアル、バリアント、ペイロード、レイヤーをサポートし、SOPからUSDモデルを作成するためのネットワークスニペットを配置します。

レイアウト

  • Editノード

    ビューア内でインタラクティブにPrimsをトランスフォームさせます。物理衝突を使用して、プロップを現実的に配置することができます。

  • Layoutノード

    インスタンス化されたUSDアセットをシーンに取り込むツールが備わっています。個々にコンポーネントを配置したり、カスタマイズ可能なブラシを使って色々な方法でコンポーネントをペイント/スキャッターしたり、既存のインスタンスを編集することができます。

  • カスタムレイアウトブラシ

    Layout LOPの挙動をカスタマイズして利用可能なレイアウトブラシデジタルアセットの作成方法。

シェーディング

  • シェーダフレームワーク

    シェーダノードのUSDプリミティブへの変換を含む、Solarisシェーディングフレームについて説明しています。

  • SolarisでのMaterialXの使い方

    HoudiniにはMaterialXシェーダノードに呼応させたVOPノードが用意されています。これらのノードを使用してシェーダネットワークを構築したり、既存のMaterialXシェーダをインポートすることで、(HoudiniのUSDレンダラーの)KarmaでMaterialXシェーダノードを利用することができます。

  • UDIM

    テクスチャ空間の異なるタイルを、それぞれ別の解像度で、異なるテクスチャファイルにエンコードすることができます。その後、kaiju.exrといったテクスチャファイル名を指定すると、Houdiniがロード時にそのトークンを特定のタイルアドレスに置き換えてくれます。

Karmaレンダリング

チュートリアル