【Blender 5.1】Gridとは?使い方や概念:ジオメトリノード

blender
記事内に広告が含まれています。

Blender 5.0や5.1で追加されたGrid系ノード(Mesh to Density Grid, Sample Gridなど)について、その概念と使い方についてまとめていきたいと思います。(SDF系の機能については除きます。)

  • Gridとは?(そもそもボリュームとは何が違うのか)
  • Density GridやSDF Gridの違い
  • フィールドとGridのデータの違い
  • Gridの基本操作

この記事では、主に場として使うGridについて解説しています。Gridとはなんなのか、そしてそれを使うために、周辺のノードのざっくりとした使い方などをまとめて基礎的な操作フローなども書いています。

Volume GridについてのBlenderのページ

スポンサーリンク

そもそもVolume(ボリューム)とは何か?

Volume(ボリューム)って聞くと、大体の人は

  • 煙、雲、霧、炎、などの気体
  • 水などの液体
  • メッシュの中身

を表現するときに使うもの、みたいに思うと思うんですが、まぁ大体その通りです。
結局、スザンヌとかのメッシュは表面しかないですよね。中身はスカスカのジオメトリです。
気体や液体とか、中身は表現できません。

それに対してボリュームは、空間をグリッド状に分割し、その各位置に値(密度など)を持たせたデータ構造です。
メッシュが表面(ポリゴン)で形を表現するジオメトリなのに対して、ボリュームは内部まで含めた密度の分布を扱えるジオメトリです。

Volume(ボリューム)のデータ構造

これまでもボリュームは扱えましたが、その内部データを直接編集する手段はほとんどありませんでした。

メッシュであれば、頂点や面を移動・削除するなどして直接形状を編集できますが、ボリュームの場合は
メッシュ → ボリュームに変換する
といった使い方が中心で、内部の値そのものを操作することは困難でした。
そのため、一度メッシュを編集してからボリュームに変換する、という回りくどい手順が必要でした。

しかし、Blender5.0から、ボリュームも中のデータそのものを編集できるようになりました。
そして、ボリュームのデータ構造は今までメッシュで扱っていたものとは全く異なるものになっています。

  • メッシュ…頂点・辺・面の接続関係(トポロジー)でできたジオメトリ
  • ボリューム…空間をグリッドで分割し、その各ボクセル(または格子点)に密度や速度などの値が格納されたジオメトリ
項目メッシュボリューム
データの場所表面空間(グリッド上)
データの単位頂点・辺・面ボクセル
構造接続関係(トポロジー)分布構造(Grid)
※Gridで言われるトポロジーとは「データが存在している場所とその広がり方」でマスクみたいに言われることもある
スポンサーリンク

Gridとは

BlenderのVolumeは、内部的にはグリッド構造(Grid)で管理されています。

グリッド構造とは、空間をボクセルで区切り、その各ボクセルに値(密度など)を持たせたデータです。

Volumeは、こうしたGridを複数まとめて保持するコンテナのような存在です。

Volume = コンテナ(入れ物)
Grid = 中に入っているデータ本体

Gridの種類

1つのVolumeが複数のGridを持つことができます。例えば以下のような値

  • density(密度)
  • temperature(温度)
  • velocity(速度)

また、それぞれのGridには意味があります。

  • 密度が入ったグリッド → Density Grid
  • 距離情報(SDF)が入ったグリッド → SDF Grid

Density Grid
データ型:float(数値)
密度を表す
ボリュームレンダリング用

SDF Grid(Signed Distance Field)
データ型:float(距離)
表面までの距離を持つ

  • 0 = 表面
  • マイナス = 内側
  • プラス = 外側

Vector Grid
データ型:ベクトル(方向+強さ)

  • Curl Noise
  • 流体っぽい動き

このように、Gridの種類によって扱い方が変わるため、対応するソケットも異なっています。(ソケットが違っても使えることもある)

ボクセル(Voxel)とは

3D空間の最小単位
位置ごとに値を持てる

タイル化

Blenderはメモリ節約・計算高速化のため、ボクセルをそのまま持たず、タイル(tile)単位でまとめて持っています。(タイル化

具体的には、8×8×8のボクセルを1つの塊として保存します。(同じ値が入っていた場合など)

つまりデフォルト状態ではボクセルがまとめられて荒い分布になっていることがあり、これを展開するためにはVoxelize Gridノードなどを使う必要があります。

※補足
厳密には、ボクセル内に値が完全に均一に詰まっているわけではなく、各ボクセルに定義された値が補間されることで、空間全体の連続的な分布として扱われます。

OpenVDBデータ構造

BlenderのVolume Gridは内部的にOpenVDBをベースにしており、OpenVDBでは以下のような構造でデータが管理されています。(おそらくBlenderでもこのような構造を持っていると思われる)

  • Sparse構造…メモリ節約のため値があるところだけボクセルを持つ
  • Tile構造…同じ値をタイルにまとめて1個で持つ
  • Active/Inactive…そこにデータがあるかどうかのフラグ
スポンサーリンク

フィールドとグリッド

ボリュームのデータ(グリッド)を編集できるようになったと言いましたが、グリッドのデータはフィールドとは違います。
なのでフィールドを期待するソケットにグリッドデータを受け渡しすることはできません。

フィールドを期待するダイヤモンド型ソケットは、位置を基準にして様々な数値を取得します。
f(x, y, z)=? というような関数になっており、位置情報の無いグリッドのデータを処理することができません。(ただの数値など、単一のデータはそのまま受け取ります)

なのでグリッドデータを渡すときは、Sample Gridノードなどで、一回フィールドに変換してから渡すことが必要になります。

また、グリッドはグリッド同士でMathノードでの計算ができます。

スポンサーリンク

スプレッドシートでのデータ

以下の画像はVolumeの中に入っているGridの情報をスプレッドシートで見たものです。
これを理解する必要はないかもしれませんが、詳細を知りたい方のために各項目についてまとめておきます。

  • Grid Name…Gridの名前(この場合はdensity)
    • Volumeの中には複数のGridを入れられる
      • density(密度)
      • temperature(温度)
      • velocity(速度)など
  • Data Type…各ボクセルに入っている値の型(この場合はFloat)
    • 種類:
      • Float(密度など)
      • Vector(速度とか)
      • Boolean など
  • Classどういう意味のデータかを定義してる
    • Fog Volume → 密度系(煙・霧)
    • 他にも:
      • Level Set(SDF)
  • Voxel Extent…各軸のデータ上のボクセル数(解像度)(今回は10×10×10)
    • 例えばVolume CubeノードでResolution(2×2×2)で作ると、実際見えるボクセルは1個作られますが、データとしては(2×2×2)と表示されます
  • Min Voxel…最小インデックス(3次元のインデックス)、ボクセルの座標系の原点(基本は0スタート)
  • Voxels…データ上存在しているボクセル数(今回は 1,000
    • 例えばVolume CubeノードでResolution(2×2×2)で作ると、実際見えるボクセルは1個作られますが、データとしては8個と表示されます
  • Leaf Voxels…実際に値を持っている末端ボクセル数(今回は全部アクティブなので同じ)
    • 例えばタイル化されると末端ボクセルにまで展開されないので、数が減ります。
    • OpenVDBの内部構造の話
  • Tiles…タイル(まとめてる領域)の数(0→全部バラバラのボクセルとして保持されてる)
    • 同じ値が続くとタイル化される(軽量化)
  • Size…メモリ使用量(Gridの重さ)
スポンサーリンク

Gridの基本操作

実際のノード操作はだいたいこの流れになります。(ノードの使い方の詳細は後述してます)

基本操作フロー

  • VolumeからGridを取り出す
    • 使用ノード:Get Named Grid
    • Volume → Gridに分解
    • ここで初めて中身にアクセスできる
  • Gridを加工する
    • ノイズをかける
    • 計算する(curl / gradientなど)
    • 値を書き換える
    • フィールド値を使うとき
      • 使用ノード:Field to Grid
  • Gridを使う、書き戻す
    • 名前付きでGridに保存する
      • 使用ノード:Store Named Grid
      • 新しいGridをVolumeに追加

空間全体に物理っぽい場を作れるようになりました。

ボクセル化

Gridは普段タイルで持たれています。でもこれだと細かい処理ができません。

ボクセルに展開

Voxelize Gridでタイル → ボクセルに分解

  • ノイズが滑らかになる
  • 計算が正確になる

軽量化する場合

Prune Gridで同じ値をまとめてタイル化→最適化

グリッドの変換

スポンサーリンク

VolumeからGridを取得する

Get Named Gridノードで、ボリュームから、内部データのGridを名前を指定して取得することができます。

Gridの名前はスプレッドシートGrid Nameにかいてあります。

RemoveOnにすると指定したGridデータを削除できます。Volume出力からはGridデータ削除後のVolumeが出力されます。(Grid出力からは削除前?のデータが出力されます。)

スポンサーリンク

グリッドをフィールドとしてサンプリング

Sample Gridノード

指定した空間内の位置において、ボクセルグリッドから値を取得するノードです。

Gridデータはフィールド系のソケットで受け渡しできませんが、Sample Gridを通すと、グリッドの値を、フィールドとして参照できる形にしてくれます。

パラメータ

Position(位置)
グリッドの値を評価する空間上の位置(オブジェクト空間)。各位置は、周囲のボクセルの値をもとに補間されます。

Interpolation(補間)
隣接するボクセル間で値を計算する際の補間方法:

  • Nearest Neighbor(最近傍)
    最も近いボクセルの値をそのまま返します。最も高速ですが、ブロック状で不連続な見た目になります。
  • Trilinear(三線形補間)
    周囲の8つのボクセルを使って線形補間を行います。滑らかな変化になり、一般的な用途に適しています。
  • Triquadratic(三次的補間)
    より高次(2次)の補間を使用し、さらに滑らかで連続的な結果を得られます。
    その分、計算コストは高くなります。
スポンサーリンク

フィールドからGridを作成する

さっきのグリッド→フィールドとは反対に、
フィールド→グリッドを作成する方法

Field to Gridノード

既存のグリッドのトポロジー上でジオメトリフィールドを評価し、1つ以上の新しいボクセルグリッドを生成するノードです。(※グリッドの作成にはその構造情報(トポロジー)が必要です。)
これにより、フィールド入力から、密度・温度・速度・距離場などのボリュームデータを直接作成できます。

各入力フィールドは、指定されたトポロジーグリッドのボクセル位置でサンプリングされ、同じ解像度・トランスフォーム・ドメインを持つ対応する出力グリッドが生成されます。

スポンサーリンク

ボリュームにグリッドを名前をつけて保存する

Store Named Gridノード

Store Named Gridノードは、ボクセルグリッドを指定した名前でボリュームジオメトリ内に保存するノードです。
これにより、1つのボリュームオブジェクト内に複数のグリッド(例:density、temperature、velocityなど)を含めることができ、後でGet Named Gridノードを使って取得できます。

同じ名前のグリッドがすでに入力ボリューム内に存在する場合は、新しいグリッドで上書きされます。

スポンサーリンク

タイル化されたボクセルを展開する

Voxelize Gridノード

Voxelize Gridノードは、スパース(疎)なボクセルグリッドに含まれるアクティブタイルを展開し、すべての領域を密なボクセルとして扱える状態に変換するノードです。
通常、SDFやフォグボリュームでは、値が一定の領域はタイルとしてまとめて保持されますが、このノードによってそれらも個々のボクセルに分解されます。

その結果、近傍ボクセルを参照するような処理(フィルタリングや精密なサンプリングなど)が正しく行えるようになります。

解像度(32,32,32)だと、(8×8×8)個のボクセルが同じ値だった場合、1個のタイルとしてまとめられてしまい、全てのボクセルがタイル化しています。それをVoxelize Gridノードで展開すると、それぞれのボクセルに細かい値が入るようになります。

スポンサーリンク

ボクセルをタイル化する

Prune Gridノード

Prune Gridノードは、ボクセルグリッド内の値がほぼ同じ領域(均一な領域)をまとめて簡略化し、データを軽くするノードです。
これにより、メモリ使用量が減り、処理も高速になります。

このノードは、Voxelize Gridノードの逆の処理を行います。
Voxelizeがスパースな構造をすべてボクセルに展開するのに対し、Pruneは均一な領域を再びまとめてスパース化(圧縮)します。

特に、塗りつぶし・クリッピング・しきい値処理などで同じ値が広がる処理の後に効果的です。

パラメータ

Mode(モード)

グリッドをどのように簡略化するかを指定します:

  • Inactive
    非アクティブなボクセルやタイルを、まとめて非アクティブな背景タイルに変換します。
    空の領域を整理する、基本的な軽量化モードです。
  • Threshold(しきい値)
    値がほぼ同じ(指定したしきい値以内の差)で、かつアクティブ状態も同じ領域をまとめてタイル化します。
  • SDF
    SDF(符号付き距離場)専用のモード。
    非アクティブな領域を効率よくまとめてノード化します。
    特に、内部・外部が広く一定値になっているSDFで高速に処理できます。

Threshold(しきい値)

この値以下の差であれば「同じ値」とみなされます。

  • 値を大きくする → より強く簡略化(細かい違いを無視)
  • 値を小さくする → 細部を保つ(あまり簡略化しない)
スポンサーリンク

参考リンク

Gridの使い方、概念説明として以下の素晴らしいチュートリアルを参考にしています。

コメント