[Solaris] HDAカメラのインポート

問題 SolarisにSceneImportLOPでカメラをインポートする際、自前のHDAカメラをインポートしようとするとワーニングがでてインポートできません。 (自前のカメラとはこういうHDAです) 以下のようなワーニングが表示されます。これはおそらく19.5以降でしか表示されないかもしれません。 解決策 まずは言われた通り、リンクに飛びましょう。 以下のような記述が冒頭にありますね。カスタムノードをLOPに読み込むにはなにか作業が必要なようですね。 Scene Import LOPが特定のHoudiniオブジェクトノードタイプをUSDに変換する方法をカスタマイズすることができます。 これは、特にカスタムノードタイプ(例えば、プロプライエタリなレンダラー関係のライトタイプやカメラタイプ)の変換に役立ちます。 その後を読み続けると色々Pythonやら書いてありますね。でもちょっと長いので無視します。 Houdiniはカスタムできるものについては、インストールフォルダにだいたいのものがバイナリになっていない状態で保存されてるので、それをコピーしてから始めるのが最短の道です。ということで以下のファイルを見てみましょう。 インストールフォルダ/houdini/husdplugins/objtranslators/cam.py import hou import husd from pxr import UsdGeom class CameraTranslator(husd.objtranslator.Translator): def shouldTranslateNode(self): return True def primType(self): return 'Camera' def populatePrim(self, prim, referenced_node_prim_paths, force_active): super(CameraTranslator, self).populatePrim(prim, referenced_node_prim_paths, force_active) cam = UsdGeom.Camera(prim) proj = self._node.parm('projection').evalAsString() if proj == 'perspective': cam.CreateProjectionAttr('perspective') elif proj == 'ortho': cam.CreateProjectionAttr('orthographic') # A few of the parameters need to be converted into 1/10 scene unit space stage = prim....

<span title='2023-10-05 09:27:07 +0900 +0900'>10月 5, 2023</span>&nbsp;·&nbsp;2 分&nbsp;·&nbsp;Shohei Okazaki

Houdini Workflowについて

いままで何回もHoudini Workflowをつくってきたので、どんなことをやっているか紹介したいと思います。 小規模な会社にいるからとか個人でやってるから、そんなの必要ないと考える人もいるかもしれませんが、そうは思いません。数人の会社で働いたことがありますが、確実にワークフローが少しでもないと良いパフォーマンスを出すことをできません。 大規模な会社には専任のTDがいてパイプラインがしっかりあり、色々便利なこともあります。反面、大きくなりすぎた会社ほど、やる気のない人や老害がたまり自由度がなくなり最新の流れにもついていけなくなったり、ワークフローを作るのに大工事したり、パイプラインにも手をいれなければいけないみたいなことも起こってしまいます。小規模だとパイプラインを作るのは難しいですが、ワークフローは自分たちの好きに作りやすいです。自分たちにあったものを構築できれば、小回りがきいて大きな所に負けないワークフローを構築しアドバンテージにすることも出来ます。 ワークフローは、TDの人やスクリプトをかける人が作るものだと考えるでしょうが、実際に作業するアーティスト主導で構築するべきです。なぜならそのワークフローを使うのは作業者であり、なにが必要なのかを知ってるのは作業者であるアーティストだからです。 パイプライン? ワークフロー? そもそもパイプラインとワークフローの違いはなんなんでしょうか? パイプラインは、別部署へのデータを送る時、たとえばアセットデータやアニメーションデータやレンダーイメージのパブリッシュなど です。決められた場所かつ安全な場所にパブリッシュしたり、決まったフォーマットに変換したりします。また、ファイルの命名規則やチェック方法やShotgunとの連携もこちらの役割です。 ワークフローは、アーティストがショット作業をする時に必要なルール・ツール を用意しておくことです。 パイプラインはTDが担当しますが、ワークフローは出来る限りそのツールや流れを熟知した人が作るのに携わるのが良いと思います。そしてFXはPythonは書けて当たり前なので、TDにお前らどうせ自分たちで出来るからとか言われ、他の部署を先にやってからと後回しにされがちです。 目的 まずは何のためにワークフローを作るかの目的をしかっり決めましょう。 私はいつもアーティストが絵作りだけに集中できる環境を作ることを目的にし、できるかぎりのことをするようにしています。 何を基準にツールやルールを作るかというと、基本この2つをベースに考えます。 ヒューマンエラーをなくす 毎回同じことをしたくない 代表格は、キャッシュやレンダーの出力先を毎回入力することです。これはもはや人間のやることではありません。 チームで新しくワークフローを作る場合は、みんなの意見を聞いて不便なことや要望を洗い出してあげることも大事です。 チームにジュニアレベルの人やHoudiniに詳しくない人がいるとしたら、色んなレベルの人にもスムーズにいくルールを考える必要があるかもしれません。 環境変数 まずプロジェクト固有の変数について考えましょう。変数は、 プロジェクト全体に適用されるグローバル変数と、シーケンスやショットごとに値が変わるローカル変数にわけられます。 プロジェクト名やシーケンス名を定義しとくとフォルダの移動やアウトプット先を決めるのが楽になります。ただこの変数はパイプラインとして設定されてることが多いです。小規模な会社や個人では自身で設定してもいいと思います。これらを設定することによってどういうことが出来るかはあとで説明します。 PROJ = 'BurningProj' 他のソフトからAlembic等でデータを持ってきた時、シーンスケールを正しくしてあげる必要があります。なぜなら、Houdiniのシミュレーション系ノードのデフォルト値は、1Grid=1mを前提として値が設定されています。これにあわせてやるのが一番良いです。 大抵の場合はインポートしたものを0.1倍か0.01倍すればいいでしょうが、海外のクライアントからもらったデータはメートルでなくインチで作業してる場合があります。その場合は39.37で割る必要があります。覚えたくないですよね。なので、コレも変数にしておきましょう。 SCALE_FACTOR = 10 他には、レンダーサイズも変数にしてもいいかもしれません。 RENDER_RES_X=1920 RENDER_RES_Y=960 また、WinodwsやLinuxのプラットフォームが混在してる場合、マウントするところを変数にしたとき、少し便利になります。どいうことかというとWindowsはZ:/proj/BuringProjがLinuxでは/proj/BuringProjの場合、$PROJ_ROOT/BuringProjという書き方に統一できます。協力会社によってはクライアントと同じドライブレターが使えないときは、協力会社に$PROJ_ROOTをX:/good_client/A_Inc/projみたいに設定してもらえれば、フォルダ構造を維持したままシーンファイルを渡せば、別の環境でもシーンを容易に再現できる可能性が高まります。 PROJ_ROOT = 'Z:/proj' 日本でもNetflixの仕事が増えてきたせいか、やっとColorMangementが浸透してきましたね。Houdiniも他のソフト同様、OCIOの環境変数を設定してあげる必要があります。ACTIVE_VIEWSはなくてもいいです。VFXではシーケンスやショットごとでLutが違う場合があるので、OCIO_ACTIVE_VIEWSを変動出来るようにしてもいいかと思います。 OCIO='/proj/BurninigProj/tools/OCIO/will_be_beautiful.ocio' OCIO_ACTIVE_VIEWS='Rec.709' ローカル変数の代表は、シーケンスとショット番号、フレームレンジとかでしょうか。 SEQ = 'seq_01' SHOT = 'shot_003' P_START = 1001 P_END = 1032 さて、これらをどうやって全員に行き渡せるかですが、大きい会社ならランチャーがあると思うので、そこで設定してもいいです。 小さい会社や個人の場合は、パッケージを使うといいでしょう。 https://www.sidefx.com/ja/docs/houdini/ref/plugins.html たとえば/proj/BurningProj/tools/houdiniというフォルダの中にプロジェクトのHDAやスクリプトを置き変数を定義するとします。 /proj/BurningProj └── tools └── houdini └── otls └── packages └── scripts └── toolbar └── maya └── nuke まずメインのパッケージを作ります。これをpackagesフォルダのBurningProj....

<span title='2021-04-29 12:27:07 +0900 +0900'>4月 29, 2021</span>&nbsp;·&nbsp;4 分&nbsp;·&nbsp;Shohei Okazaki

FX的 Height Fieldの使い方

今回は、Height Fieldです。 FXは、Height Fieldの恩恵は、あまりないと思いますが、個人的なFX的使い方を紹介します。 サンプルファイルです。17.0.459で作成。 Download Terrain Object Height Filedの実装にともないTerrain Object DOPにUse Heightfiledというオプションが追加されました。 今までは、Particleと地面の詳細なコリジョン結果を得るには、このノードのVolumeに変換する所のオプションにてDivisionSizeをあげて高解像度にするか、StaticObjectをつかってSurface Collisionを使用したりしてました。どちらも、軽いものではありませんね。 Height Filedは、どこかの軸が2000を超えてもなんてことありません。普通のVolumeのならめっちゃ重いですよね。これを使うなんて、さすがSideFX。 さて実際の使い方は、Environment Modeler等が作ってくれた地形等を読み込み、HeightField ProjectでHeightFiledに変換します。 シミュレーションの範囲を決めて、より効率的に作業するならHeightField Cropを使いましょう。 小さな石とかデブリがあったら、それごとProjectionしても、そこそこ使えます。 え、Displacement・Bumpを使ってたらどうするんだって? Point CloudでUVを持ってきて、Textureをインポートして、 足し算。 それだとNormal考慮してないってか。インポートしたGeometryをSubdivisionをめっちゃかけて、SopでDisplacementするしかないですかね。 Packでコレ使うと、めっちゃ重いからVolume Collision使わないで、普通にBulletでConcaveにしたほうが良いです。 Boolean Cutter 続いては、別の使い方の紹介。BooleanのShatterに使ってみましょう。 そもそもBooleanを使う時の重要な点は、如何にエラーのないGeometryを作り出しレンダリングできるようにするかです。「エラー」とはManifold Topologyになっていないものが生成されたり、Alembicを使って他のツールにGeometryとしてインポートするときに起こりうる問題の要因のことを指します。Houdini内で完結する場合は、これらの問題があっても気にせずレンダリングできることが多々です。 なぜBooleanに使うのか?それはHeightFiledの特徴が気に入ったからです。 特徴1:軽い 前述した通り挙動が軽いです。破壊の断面はディティールが欲しくなります。通常だったら、面を細かく分割してPointにNoiseをかけたりしますが、結構動作重いです。軽いは良いです。 特徴2:Topology HeightFieldをPolygonにコンバートして、それをDisplacementした方向からTopoloyを見ると綺麗な格子状になっています。 エラーTopologyを最も生成しやすい要因は、このNoiseのカッターを作ってる時です。GeometryのPointsに対して、強いNoiseをかけると、自身の面と干渉してしまいます。これは、あまり良くないです。 そして、綺麗なTopologyということは、ここからUVが作りやすいです。 それでは、実際の手順の説明です。 基本的には普通よくあるやつと似てます。Point作ってHeightFiledのGridをコピーしてNoiseをかけます。 Noiseをかける前に対象Geometryより少し大きめなBoundigBoxを使ってCropしてあげれば、より効率が良くなります。 続いて、HeightFiledをMeshにコンバートし、UV ProjectでDisplacement方向からUVを転写。UV Layoutで一度整えます。このままだと高さが考慮されていないので、heightというPointAttrを使ってUVを調整します。 Wrangleで縦横比をheihgtで乗算 vector bsize = getbbox_size(0); float mult= bsize[0]/bsize[2]; @uv.y = point(0,"height",@ptnum)*mult; 最後に、UV Layoutでもう一度整えておしまいです。 Cutterの用意ができたら、あとは通常通りBooleanでShatterしましょう。 その後は、Normal入れたり、 Non-Manifoldを取り除くために、CleanかPolyDoctorで治しときましょう。エラーは出るときは出ます。 ここまでUVがあれば、ModelerやLookDevにTexture・Shaderを作ってもらうために壊したものを戻しても、文句は言われないでしょう。きっと。 ということで、今回は本来の用途とは違った使い方の紹介でした。 他にも、こんな風に本来の目的とは違う使ってるよって方いましたら、ぜひ教えてください。

<span title='2019-02-12 09:30:42 +0900 +0900'>2月 12, 2019</span>&nbsp;·&nbsp;1 分&nbsp;·&nbsp;Shohei Okazaki

最近のお気に入り - 1 「右クリック」

大したことじゃないけど、最近のお気に入りを紹介するコーナ。 第一弾は右クリック。 FXを作ってく上で、僕には2大裏テーマというものがあります。それは 「キーフレームを極力打たない」と「手の挙動範囲を極力少なくする」 です。今回は後者のために、必要なカスタマイズです。 ノードのプリセットに入れればいいじゃんと言う人もいるかもしれないですが、あれはパラメータの並び順や位置のレイアウトも記憶しています。Houdiniはバージョンが変わると、パラメータのレイアウトが変わることなんてことは当たり前なので、バージョンごとにプリセットを更新する必要があり非常にめんどいのです。といわけで右クリックのメニューにサポートツールを追加して効率化を図っています。 メニューの追加の仕方ですが、 ノードを右クリックした時にメニューを追加するには、OPmenu.xmlを編集します。 パラメータを右クリックした時にメニューを追加するには、PRAMmenu.xmlを編集します。 基本的には、ここに書いてあるんで、読めばわかります。 http://www.sidefx.com/docs/houdini/basics/config_menus.html お題として、先日パベルさんのセミナーでDescriptive Parmの表示の仕方を習ったので、これをパラメータの右クリックに追加してみましょう。 Descriptive Parmとは、File Sopなどにある、Network View上でノードの名前の下にあるやつです。 これを、表示されてないノードにも表示させるようにします。これで、いちいちノードを選択してパラメータを見なくても、重要なパラメータの値がNetwork View上で確認できるようになります。しかし、そのパラメータが何かのノードとリンクして、そのノードはクソ重い処理をしなければならないのなら、この値を表示するために、毎回時間がかかってしまうので、気をつけてください。 最初に、Pythonでどうやるか確認しましょう。ヘルプを見るとノードのUserDataを変更すれば、いいようです。 http://www.sidefx.com/docs/houdini/network/badges.html#textbadges 上の添付のようにMountainSopのElement Sizeを、Network Viewに表示させるには、Pythonはこんな感じ。 node = hou.node('/obj/geo1/mountain1') parm_name = 'elementsize' node.setUserData("descriptiveparm", parm_name) ノードと、Descriptive Parmになるパラメータの名前が必要ですね。 必要なものがわかったので、実際の作業に入りましょう。まずはPythonファイルを作ります。ここでは、changeDescriptiveParm.pyという名前にして、Houdiniがインポートできる場所に保存します。 import hou def doit(parms,type): parm = parms[0] parm_name = parm.name() node = parm.node() if type == "clear" parm_name = "" node.setUserData("descriptiveparm", parm_name)) 現在、右クリックしているパラメータが何かはparms=kwargs["parms"]で取得します。parmsとあるとおり、リストとして値が返ってきます。選択してるパラメータは1つなので、parm = parms[0]。パラメータからノードの情報を得るには、単純にparm.node()。これで、必要な情報はすべて取得できたことになります。 Descriptive Parmをクリアしたい時もあるので、parm_nameを空にして、それを可能にしておきます。 最後に、PARMmenu.xmlを編集しましょう。こうです。 <?xml version="1.0" encoding="UTF-8"?> <menuDocument> <menu> <subMenu id="changeDescriptiveParm"> <label>Change Descriptive Parm</label> <scriptItem> <label>Set</label> <scriptCode><!...

<span title='2018-03-06 12:00:18 +0900 +0900'>3月 6, 2018</span>&nbsp;·&nbsp;1 分&nbsp;·&nbsp;Shohei Okazaki

[Deadline] Add Extra Version

時々、悩んでる人がいたので、Deadlineネタを1つ。 どんなソフトでも、マイナーアップデートは簡単にできますが、メジャーアップデートは、プロジェクトの兼ね合いや自社Plugin/Toolの影響で、そうは容易くできません。アップグレードの金を出すのに渋って更新してないのでなく、ただ単にめんどくさいという理由で更新されてなかったら、担当者のケツを蹴っ飛ばして更新してもらいましょう。 いろんな理由でDeadlineのバージョンが古すぎて、最新のHoudiniのバージョン使用できないという人もいるでしょう。今回は、そんな人向けへの裏ワザを紹介します。 ※この記事は、Deadline Client Version: 9.0.6.1の元、作成しています。 Configure Plugins まずは、 Configure Pluginsに任意のバージョンを追加して、Pathをセットできるようにしましょう。 以下のファイルを探しだして、[Houdini16_Hython_Executable]の次に追加します。 $DEADLINE_REPOSITORY/plugins/Houdini/houdini.param [Houdini17_Hython_Executable] Label=Houdini 17 Hython Executable Category=Render Executables CategoryOrder=0 Type=multilinemultifilename Index=8 Default=C:\Program Files\Side Effects Software\Houdini 17.0.000\bin\Hython.exe;C:\Program Files (x86)\Side Effects Software\Houdini 17.0.000\bin\Hython.exe;/Applications/Houdini/Houdini17.0.000/Frameworks/Houdini.framework/Versions/17.0.000/Resources/bin/hython Description=The path to the hython executable. It can be found in the Houdini bin folder. そうすると、Configure Pluginsをみてみると追加されています。簡単ですね。各自インストールフォルダを指定してあげてください。 Distribute Sim使う人は、Sim Trackerも追加しときましょう。(HQueue使う人ってどれくらいるんだろう?使わないよね?) Buildを指定したいなら、Houdini16.5.123_Hython_Executableみたいに作ることも可能です。 Mantraも同じ要領でやればできます。 Houdini Submission Submission WindowのVersion指定メニューに、任意のバージョンを足すには、以下のpythonを変更します。 $DEADLINE_REPOSITORY/scripts/Submission/HoudiniSubmission.py 以下のラインを探しだして、任意のバージョンを追加してください。 scriptDialog.AddComboControlToGrid("VersionBox","ComboControl","14",("9","10","11","12","13","14","15","16","17",), 5, 1) これだけです。 Deadlineは結構いいよ 以上の手順を踏めば、投げられるようになったと思いますが、 Deadlineはバッチ処理をする前に、いくつかのプロセスを処理してるので、あまりにも古いバージョンを使用してる場合は、ノードのパラメータ名が変わっていたり、対応してないかもしれません。 そんな時は、$DEADLINE_REPOSITORY/plugins/Houdini/hrender_dl.pyをなんとかなります。...

<span title='2017-09-13 11:00:53 +0900 +0900'>9月 13, 2017</span>&nbsp;·&nbsp;1 分&nbsp;·&nbsp;Shohei Okazaki