2016-01-15

pscale from camera distance

カメラからパーティクルまでの距離を算出し、それを元にパーティクルの大きさ (pscale) をコントロールする方法を紹介する。ここでは、距離の算出をこの目的には一件無関係に見える UV Texture ノードを使い、距離値を Attribute Wrangle を使って渡す。


使用したビルド: Houdini 15.0.346
参考シーンファイルへのリンクは一番下にあり。

おおまかな流れ

  1. シーンの作成
  2. pscale の定義
  3. レンダリング
  4. IFD ファイルサイズ
  5. おまけ

1. シーンの作成

    シーンのベースは packed primitives を紹介したページ
    1. ポイントクラウド生成
    2. ジオメトリのアサイン
    を流用する。ここでは、
    • rubber toy の大きさを定義する transform1 の Uniform Scale を 0.1
    • パーティクルの数を定義する scatter1 の Force Total Count を 100
    としている。
    ここまで設定が終わったら、ビューを好みの位置にして、Lights and Cameras シェルフから Camera ツールを Ctrl キーを押しながらクリック、カメラ (cam1) を作成。

    このビューを元に cam1 から各パーティクルへの距離を算出、算出した値を pscale に付加する。

    cam1 の視点を変えるにはビューポート右上の黄色いメニューから cam1 を選択した上で、右側にある (Lock Camera/Light) をクリックしてオンにする。オンにしなければ、ビュー変更時にカメラ選択が解除される。変更後はアンロックするのが望ましい。

2. pscale の定義

各パーティクルとカメラの距離の算出には、UV Texture ノードを使用する。

  1. ネットワークビューで TAB -> Material -> UV Texture を実行。作成された uvtexture1 を scatter1 と copy1 の間に挿入。
  2. uvtexture1 ノードのパラメータを以下のように設定する。
    • Texture Type を "Perspective From Camera"
    • Camera に /obj/cam1
    • Attribute Class を Point

  3. uvtexture1 を選択したまま、Geometry Spreadsheet を見ると、uv[0], uv[1], uv[2] アトリビュートが追加されていることが確認可能。このうち、uv[2] の値がカメラから各パーティクルまでの距離になっている。

    この uv[2] を pscale に渡す必要がある。
  4. TAB -> Attribute -> Attribute Wrangle を実行。作成された attibwrangle1 を uvtexture1 と copy1 の間に挿入。
  5. attribwrangle1 の VEXpression を

    @pscale = @uv.z;

    と指定する。ビューポートのオブジェクトは、cam1 から見ている場合、距離に関係なく同じ大きさで表示される。

    一つ一つが大きすぎれば、transform1 の Uniform Scale の値を小さくするか、VEXpression を

    @pscale = @uv.z/3;

    等とする。

    cam1 から外れて横から見ると、cam1 (左側のカメラ) に近いオブジェクトは小さく、遠いオブジェクトは大きいことがわかる。

3. レンダリング

  1. この状態で Render View へ行きレンダリングを実行すると、パック化されたオブジェクトはマテリアルが付いてこない。
  2. /out 以下の Mantra (mantra_ipr) ノードを選択、Rendering タブ -> Render タブの一番下にある Declare Materials を "Save Only Referenced Materials" (デフォルト) から "Save All Material SHOPs" に変更、再度レンダリングを実行する。

    こうすることでマテリアル付きでレンダリングが可能。

  3. 「再度レンダリング」とは、Render View 上の をクリックして実行中の IPR レンダリングを終了した上で "Render" ボタンを再びクリックして再開すること。もしくは IPR を介さずに、Mantra ノード (/out/mantra_ipr) 上の Render to Mplay をボタンをクリックすれば、Mantra ノードの変更がすべて IFD ファイルに更新され、出力結果は Mplay に表示される。IPR は基本的に IFD の再出力を行わない。

4. IFD ファイルサイズ

  • packed primitives のページ同様、copy1 の Stamp タブ以下の3つ
    • Stamp Inputs
    • Cache Stamping Geometry
    • Pack Geometry Before Copying
    で Pack Geometry をオンにせずに出力した場合のIFD のファイルサイズは 1.4GB (IFD の出力方法はこちらにもあり)。
  • 上記の3つをオンにして、Mantraの Declare Materials を "Save Only Referenced Materials" (デフォルト) にして出力した IFD の大きさは、約 1.5MB。
  • Declare Materials を "Save All Material SHOPs" にした場合約 1.7MB。どちらもほぼ 1/1000。
  • Packed Geometry をキャッシュファイルとして書き出した場合 (1.0MB 程度) ほどでないにせよ、ファイルサイズを小さくすることが可能。マテリアルの取り回しはこちらの方が簡単かもしれない。

おまけ

例えば、インスタンスコピーしたオブジェクトを常にカメラの方に向けたいとする。これも Attribute Wrangle の中で対応可能。
attribwrangle1 の VEXpression に、

vector p1 = {0,0,0} * optransform("/obj/cam1");
vector p2 = {0,0,0} * optransform("/obj/grid_object1");
@N = normalize(p1-p2);
@up = {0,1,0};
と追加。

カメラ (cam1) をどのようにタンブルしてもオブジェクトは常にカメラ方向を向くようになる。大きさも揃っているので、良いように解釈すれば、2Dっぽい表現が可能。

まとめ

  • Packed Geometry により、著しいファイルサイズ、メモリの軽減が可能になる。
  • カメラからのパーティクル (ポイント) までの距離を得るには UV Texture ノードを "Perspective From Camera" 設定で使用することで可能。このノードを使うことで、複雑な式を書くことを回避できる。
  • マテリアルのついた Packed Geometry をレンダリングするには、Mantra ノードのDeclare Materials の設定を "Save All Material SHOPs" または "Save All SHOPs" にすることで可能になる。
  • 関連項目
  • シーンファイル:
    • pscaleFromCameraDistance.zip (50KB)
      「おまけ」の部分は attribwrangle1 でコメントアウトされているので、実行するには行頭の "// " を削除する。


最終更新: 2024-04-05

0 件のコメント:

コメントを投稿