各所で擦られたネタではありますがメモのために。
Houdiniは保存時のデータをしっかり削減してあげることでメモリ不足で落ちなくなったりする可能性が上がります。
その後の処理の面でもデータサイズが軽いほうが何かと便利です。HDA化したりしときましょう。

以下いろいろなVolumeのデータ削減の紹介
- Houdini Volumeか?VDBか?
- 削減後の比較
- VDB Vector from Scalar
- Resample
- Deactivate
- Active Intersection
- 16bit float
- Delete Attributes
- おまけ
Houdini Volumeか?VDBか?
基本的にはVDBのほうが軽いため、VDBで保存しましょう。
ただし、レンダリングや別DCCで使うための書き出し以外では拡張子はvdbにせずに、bgeo.scで運用するほうが便利です。
保存されるアトリビュートに違いがあり、削除したはずの不要なアトリビュートが復活したりします。


削減後の比較
もちろん合わせて使用しないとあまり効果がないものもある。
元のファイルサイズ:241.8 MB
| 方法 | ファイルサイズ |
|---|---|
| VDB Vector from Scalar | 241.5MB |
| VDB Vector from Scalar + Resample | 63.5MB |
| Deactivate | 246.1MB |
| Active Intersection | 92.0MB |
| 16bit float | 132.8MB |
| Delete Attributes | 241.8MB |
VDB Vector from Scalar
vel.x,vel.y.vel.zのFloatのVolumeをVectorのVolumeにまとめます。VrayやArnold等外部レンダラーに持っていく際にはほぼ必須です。
少しファイルサイズが減ります。

Resample
特にvelのVolumeに対して、Vector型な上にレンダリング等でそこまで細かい解像度がなくても成立することが多いのでResampleでVolumeの解像度を落とします。
劇的にファイルサイズが変わります。影を落とす用Volumeだけ落とすとかもあり。
Pyro Solver SOPのVelocity Voxel Scaleだとシム中のVelフィールドが指定値で乗算された解像度になります。
Deactivate
VDB Activateを使用して各Volumeの値の差の少ない部分を削除します。
シェーダーで値をMultiplyしている場合等、レンダリングにかなり影響する場合があるので使用は難しいですが、ちょっとだけファイルサイズが減ります。
高解像度のVolumeや薄い部分が大量にある場合はやってあると効果が出やすいです。例の爆発ではあまり効果なし。
レンダリングに使用しない中間データであればToleranceを結構上げるとデータ量削減になります。

Active Intersection
densityがない部分にもvelやtemperatureがある場合があるのでそれを削除します。これは結構削減できることが多いです。
作例はtemperatureもdensityで削っていますが、temperatureはflameを基準で削ってあげたほうが削減できます。
ギリギリだとエラーになる可能性があるため。基準となるVolumeの範囲を1〜2くらい広げておきます。


16bit float
Primitive PropertiesでWrite 16bit floatsにチェック。
16bitで保存した場合、極端に巨大なbboxだったり、値が一定以上だとVoxelの値がinfになって正しく保存されません。
保存時に16bit変換されるため、保存されたキャッシュを読み込むまでは値がおかしくなっているかどうかはViewportやGeometry Spreadsheetではわかりません。
Voxelの値が高すぎるかどうかは後述のmin/maxで取得できます。

Delete Attributes
Pyro Solver SOPやPyro Bake Volume等で不要なアトリビュートがついている場合があるので削除する。

おまけ
Camera Clip
VDB Clipを使用してカメラの範囲外or内を削除します。
もちろんレンダリングに影響するため、したほうが良いかは考える必要があります。


Occlusion Culling
カメラから見て手前にあるSDFで遮られて見えない部分のVolumeを削除する。

カメラ手前のオブジェクトをSDFにし、

VDB Occulusion MaskノードでSDFとカメラからVolumeを作成します。

作成されたVolumeをしきい値にしてVolume Wrangle等で重なっている部分を削除
if(volumesample(1,0,@P) >= 0.001 ) {
f@density *= 0;
}
Min / Max
Pyro Post ProcessにもCompute Min / Maxがついてます。ですがVolume Reduceノードを使用しているのでVDB Volumeの場合は正しく計算されていません。
計算する場合は(知る限り)一度Houdini Volumeに戻す必要があります。
値が分かればシェーディングの目安にもなりますし、この後の値の参考にもなります。

VDBから一度Volumeにし、Volume Reduceで再計算します。

その後Primitive Wrangleを使って取り敢えず力技で値を設定
s@__valuetype = primintrinsic(0, "vdb_value_type", @primnum);
f@minimum = 0;
f@maximum = 0;
if(s@__valuetype == "float") {
@minimum = prim(1,"minimum",@primnum);
@maximum = prim(1,"maximum",@primnum);
}
if(s@__valuetype == "vec3s") {
float min_x = prim(1,"minimum",0);
float min_y = prim(1,"minimum",1);
float min_z = prim(1,"minimum",2);
float max_x = prim(1,"maximum",0);
float max_y = prim(1,"maximum",1);
float max_z = prim(1,"maximum",2);
@minimum = min(min_x, min_y, min_z);
@maximum = max(max_x, max_y ,max_z);
}