2019-08-02

High resolution Heightfield

Houdini の Terrain (地形) ツールは HeightField という 2D のボリュームが元になっている。これを高解像度で作業する際に役立つであろう事項をまとめました。

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

  1. Sampling パラメータ
  2. Grid Spacing
  3. HeightField Resample SOP
  4. HeightField Paint SOP
  5. HeightField Split SOP
  6. 解像度 10,000 以上の出力

1. Sampling パラメータ

Houdini 17.0.338 (2018 年9月) より、HeightField SOP および HeightField File SOP に Sampling というトグルパラメータが追加されている。選択肢は Corner と Center の二つで、これによりボクセル数の計算基準を変更できる。
例えば Size が 2x2 で Grid Spacing が 1 の場合、Sampling が Center であれば、ボクセルの中心を基準とするので、ノードが生成するボクセル数は 2x2 =4 になる。
Sampling を Corner にすると、頂点数で数えられ、ノードが生成するボクセルの数は 3x3=9 ボクセルになる。

Center Corner

なお、Convert HeightField SOP を使ってポリゴンに変換すると、Sampling が Center であれば、4頂点 (面の数=1) のポリゴン面 になり、Corner であれば 9頂点(2x2=4面)のポリゴン面になり、HeightField SOP が描画した形状と同等のポリゴン形状になる。

Houdini 16.0 や 16.5 など、このビルド以前では Sampling パラメータが存在せず、 上記の設定では、ビューポートには 2x2 のグリッドが描画されていた(つまり Corner 基準) が、これを Convert HeightField で変換すると、1x1 のポリゴン面 (Center 基準) になってしまっていて、混同を引き起こしていた。
Sampling が追加されたことにより、HeightField SOP での描画がそのままポリゴン変換時と同じになるようになった。なお、Sampling の設定は Center がデフォルトになっている。

つまり、Size が 1024x1024, Grid Sapcing が 1, Sampling が Center であれば、1024x1024 のボクセルが作成され、これをマップ画像として出力すれば1024x1024 ピクセルの画像になり、ポリゴン形状に変換すれば、頂点数が 1024x1024 のポリゴン面 (面数は 1023x1023) となる。

2. Grid Spacing

Grid Spacing は Size の分割数を設定している。Size が1024で Grid Spacing が 2 であれば、作成されるボクセル数は 512 となる。
Grid Spacing を 0.5 とすれば 2048、0.25 であれば 4096 となる。

3. HeightField Resample SOP

HeightField Resample SOP を使うことで、ネットワークの任意の場所で解像度の変更が可能。 Specify Exact Resolution をオンにし、Division Method を By Size にすれば、HeightField SOP の Grid Spacing と同じ設定方法を使うことも可能。

4. HeightField Paint SOP

HeightField を含む .hip ファイルのサイズが異常に大きくなった場合、HeightField Paint SOP を疑うと良い。よくある問題としては、高解像度の HeightField に対して直接 Paint SOP でマスクを書くと見た目には荒いがデータとしてはボクセル単位の非常に重いデータが作成され、これが .hip のファイルサイズに影響する。回避策としては、以下の二つが考えられる。

  1. HeightField Draw Mask を使う。これはベクタなので解像度に依存しない。
  2. HeightField Resample SOP を挿入し、解像度を低くしてから Paint を行う。

例えば、Size が 1024x1024 で Grid Spacing が 4 の HeightField (つまり解像度 4096x4096) を作成し、これに対して HeightField Paint SOP を使い「重」という字を 10 ストローク (カーブ) 10個で描いたとする。

操作 4K のまま Resample で 1K に落とす
Noise と組み合わせた結果
保存時のファイルサイズ 26.1MB 2.5MB

ちなみに Resample で 8K にして HeightField Paint で Recache Strokes をクリックした後に .hip ファイルを保存すると 104MB になるが、出来るマスクのクオリティは殆ど変わらない。

なお、マスクを反転するには、Heightfield Wrangle SOP を追加し、

@mask=1-@mask;
とするのが一つの方法。

5. HeightField Split SOP

HeightField Split SOP を使うことで、HeightField をタイル状に分割することが出来る。ドキュメントには

例えば、for-eachループで各タイルを個々のファイルに保存します。
とあるが、サンプルが提示されていないので、以下に紹介したい。

HeightField を作成し、HeightField Noise を加えたものに、For Each ループで HeightField Split を実行し、さらに効果を加えるとする場合

  1. heightfield_noise1 に HeightField Tile Split (heightfield_tilespit1) を接続。ここでは、Tile Count を 2x2 とする。
  2. TAB->For Each Count を実行。

      foreach_begin1, foreach_count1, forach_end1 の3つのノードが出来る。
  3. foreach_begin1 を heightfield_noise1 と heightfield_tilesplit1 の間に挿入する。
  4. heightfield_tilesplit1 の出力を foreach_end1 の一つ目(左)の入力に接続、foreach_end1 の設定を以下のようにする。
    • Iteration Method は By Count
    • Gather Method は Merge Each Iteration
    • Iterations は 4 (Tile Count が 2x2 の場合)

      ただしこの状態で、foreach_end1 に表示フラグを設定し、Single Pass をオンにして値を変えてもビューポートの HeightField は変わらない。
  5. heightfield_tilesplit1 を選択、ギアアイコンから Add Spare Input を実行。
      Spare Input0 が追加される。
  6. 追加された Spare Input0 を ../foreach_count1 と設定し、Loop 作成時に出来た forach_count1 ノードを参照するようにする。
  7. heightfield_tilesplit1 ノードの Tile Number に以下のエクスプレッションを挿入する。
    detail(-1, 'iteration', 0)


    foreach_count1 と heightfield_tilesplit1 の間に青い破線が引かれ、両者が関連付けられたのが分かる。
  8. これで、ループが正しく動作する。
      Single Path をオンにし、値を0と3の間で変更すれば、各タイルだけが表示される。
  9. heightfield_tilesplit1 の下流に HeightField Resample を挿入し Resolution Scale を 4 (つまり解像度を8K) に、さらに HeightField Distort を挿入すると下のようになる。
  10. 各タイルへの処理によっては、タイル間の切れ目に大きな食い違いが出てくることがある。この場合は、Height Field Tile Split で Voxel Padding の値を大きめに取り、重なる部分に余裕を持たせる。
  11. タイル分割した HeightField は HeightField Splice SOP を使って繋ぎ直して一つにすることが出来る。
      ただし、8K のタイルを4枚つなげれば、16Kx16K の HeightField になるので、メモリの少ない PC では注意が必要。

6. 解像度10,000 以上の HeightField 出力

デフォルト状態の Houdini では、解像度が10,000以上の Heightfield を HeightField Output ノードを使って出力しようとするとエラーになる。これを回避するには、Edit -> Preferneces -> Compositing の Cooking タブで、Resolution Limit を 10,000 x 10,000 以上に設定する。

    なお、18.5.640 から環境変数 HOUDINI_COP_MAXRES でも最大解像度を指定できるようになった。

おまけ: GPU -> CPU

Heightfield は、デフォルトでは、OpenCL による GPU 演算により高速に演算されるようになっている。使用するビデオカードの VRAM が潤沢でないにも拘らず高解像度の HeightField を扱なければならない場合、演算方法を CPU に変更し、VRAM の代わりにメインメモリを使うことが可能。
この変更は、Edit -> Preferences -> Miscellaneous の OpenCL Device 以下の Type を GPU から CPU に変更し、Houdini を再起動することで変更できる。変更後は CPU 演算になるので、演算速度は低下するが、メモリは (潤沢にあれば) GPU よりも多く使えることになる。 なお、この変更は、Heightfield だけでなく Pyro など他の OpenCL の計算にも影響する。

シーンファイル


最終更新: 2021-07-16

0 件のコメント:

コメントを投稿