すあまの備忘録

誰得内容の自分のための非営利目的備忘録ブログ(筆者がわかっても内緒にしてください)

Tips - HoudiniでのVolumeのデータ削減とかとかメモ

各所で擦られたネタではありますがメモのために。

Houdiniは保存時のデータをしっかり削減してあげることでメモリ不足で落ちなくなったりする可能性が上がります。

その後の処理の面でもデータサイズが軽いほうが何かと便利です。HDA化したりしときましょう。

以下いろいろなVolumeのデータ削減の紹介

Houdini Volumeか?VDBか?

基本的にはVDBのほうが軽いため、VDBで保存しましょう。

ただし、レンダリングや別DCCで使うための書き出し以外では拡張子はvdbにせずに、bgeo.scで運用するほうが便利です。

保存されるアトリビュートに違いがあり、削除したはずの不要なアトリビュートが復活したりします。

.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);
}