はじめに
こんな記事を書いている間にH18.5が発表されてPyroがめちゃアップデートされてた。
Houdini 18.5 Sneak Peek on Vimeo
備忘録なので過去の作り方としてそのまま記事に。
この記事の後半を読む前に、参考にしたMatt PuchalaさんのSample Hipを開くこと。
Axiom Solver — Matthew Puchala
全体
POP Emitter
左側
LineからSweepで半球を作成。この際に真上に穴を開けておいて真上にエミットするパーティクルができないようにする。
Normalを作成し、Scatter(このScatterの数がPOPのエミット数)
右側
Point Generateで1つだけPointを作成し、Attribute Createでエミットするフレーム番号のアトリビュートを作る。
Wrangleでエミットするフレーム番号+Durationの範囲以外の場合はPointを削除させる。
@multを作成し、あとでtemperature,burnをフレームによって調整する。pscaleも同様
if(@Frame < @stFrame || @Frame > @stFrame + chf("dur")) { removepoint(0,@ptnum); } f@mult = fit(@Frame, @stFrame, @stFrame + chf("dur"), 1,0); f@pscale = 2 - @mult;
1個だと物足りないのでPoint Replicateで3つに増やす。Attributeを引き継ぐのを忘れないように。
その後Copy to Pointsをする。
POP
POP Source
EnumerateでPointに@idを作成。
Point VOPでVelocityとmassをランダムに作成
Velocityは早いやつが何個かあり、それ以外はそんなに早くないとなるように調整。
POP Sim
POPシムはほぼデフォルトの状態。
POP SourceのAdd Inherited Velocityを使用してvにランダムを追加
POP Dragを少々かける。
POPの後でRetimeをかける。おまじない。
Pyro Source
Point Replicate
Point ReplicateでPointを増やす。
Point Replicateは、Nかvがあるとその方向を向いた状態で複製することができる。ライン形に複製するときに便利
ShapeをLineにし、OrientationをZX Plane
CenterのZを-0.5にすると最初のポイントから後ろに並ぶ。
Uniform Scaleで並ぶ長さを決め、Quasi-Stratified Sampligのチェックを外すと均等に並ばなくなる。
さらにPoint Replicateを使用し、今度はSphere上にPointをかさ増しする。
1,2回めどちらも、Copy Source Attributesのチェックを忘れないように。
ageで消す
数が多すぎるのでageで消す。
Pyro Attributes
Pyro Sourceでアトリビュートの初期値を設定。
Point Vopでageを元にMultiply
Attribute Noiseでノイズを追加
どちらもAddにはしない。Addにすると局所的に非常に高い値などが生成されてPyroのシムがぶっ飛んだりする。
Point VelocityでCurl Noiseを追加
Volume Rasterize
Pyro Sim
BBOX
今回はSparse Solverを使用しているが、
爆発はちょっとの調整でかなり範囲が広がってしまうことがあるためBBOXを作成して範囲を制限している。
DOP
Smoke Object
Boundry ConditionsのYをClose Belowにしてもいいが、Ground Planeを敷いているので設定していない。
Volume Source
- burnをflameに変更し、OperationをMaximumに。
- temperatureのOperationをPullにし、Acceleration StrengthとDeceleration Strengthを設定。
- vをvelに設定、Scaleを弱めにしてAdd
- burnをdivergenceにし、Scaleを調整。Use Timestepをオフに。
Operation : Maximum
毎フレームの追加時にすでにより高い値がBoxel内に合った場合は追加しなくなる。どんどんSourceが追加されるのを防ぐ。
Operation : Pull
Target Fieldを毎フレーム押し出す。Acceleration StrengthとDeceleration Strengthで強さが決まる。
今回の設定では、temperatureが押し出されることで外へ広がっていくような感じになる。細いパーティクルからエミットするとよくわかる。
Use Timestep
DOPの計算が24fps基準らしいので、オンだと24fpsの際に実際のScaleが等倍になる。内部的に勝手にMultiplyされる感じ。
今回は24fpsなのでほぼ関係ない。
Divergence
ざっくり言うと、+の値で膨張し、-の値で縮小する。
Pyro Solver
Resize
動きが早い場合は、ある程度上げる。
足りないとコンテナに引っかかって段差ができてしまう。
Simulation Tab
Sparse Solverは従来のGravity Forceの計算ではなく、Ambient TempとReference Tempで浮力が決まる。
この部分はK(ケルビン)表記なので、℃表記になおす場合は以下の計算で直す。
K=℃ + 273.15 ℃=K - 273.15
Advection-Reflectionを使用すると計算速度の低下と引き換えによりディテールが残るようになる。
Flame Tab
flame field(burn)から生成されるFieldと生成の仕方の制御
Shape Tab
Dissipationで煙を消しつつ、小さなTurbulenceをかけている。
TurbulenceはControl Fieldと併用しないとずっとぼこぼこしたタービュレント感が残ってしまうので注意。
Micro Solvers
Speed Fieldを作成し、Disturbance等のMaskに使用。
Speed Field
Gas Match Fieldでvelと同じ設定のSpeed Fieldを作成
Gas Analysisでvelのlengthを計算し、Speed Fieldに格納
Speed Field(別手法)
Fieldが増えるとメモリ使用量も増加するため、Fieldを増やしたくない場合
デフォルトのControl Fieldはスカラーしか指定できないため
以下のようにMicro Solver内の該当箇所のBindのTypeをvectorにし、lengthノードを間に挟めばControl Fieldにvelを指定することができ、Fieldを増やさなくてよくなる。
Gas Disturb (Rotate)
いつついたのかわからないが、Rotational Forceにチェックを入れる。
チェックを入れるとDisturbance Fieldがvelの強さを変えるのではなく、velの向きを変えるように作用する。
velの強さを維持しつつランダムな向きへvelを変更できる。
この設定の際にStrengthを上げすぎると上昇する力などの本来のvelの効果が消えてその場でぐちゃぐちゃしてるようになってしまうため上げ過ぎには注意する。
Block-Basedの設定時は、ワールド空間でノイズを生成する。Base Block Sizeはその際の一番大きいブロックの大きさ。Voxel Size以下のノイズは作れない。
Gas Disturb
Rotational Forceをオフにし、ModeをContinuousに設定。
Continuousの場合は、Voxelごとにノイズが変わるので一番小さいノイズを追加することができる。やりすぎるとわしゃわしゃする。
作例はちょっとわしゃわしゃしすぎた気がする…
VoxelごとのノイズのためVoxel Sizeの影響を受けやすく、高解像度にした場合にはStrengthを下げないとめちゃめちゃ細かいつぶつぶが発生する。
Gas Vortex Confinment
発生した渦を維持する力を追加する。いつも最後に下げがちで効果の程がなんとも言えない。
Gas Turbulence
全体にかかるTurbulence。大きいのと小さいのを作ることが多い。
強すぎるととてもTurbulenceが出るので、Control Settingsで適応範囲を決めること。
Post
はじめに、でもあるようにこれ以降はMatt Puchalaさんのサンプルの簡略実装になってます。
Cache
DOP Import Fieldで必要なFieldをSOPへ読み込み、
Pyro Post ProcessノードでVDBをにしてキャッシュする。
Apply LookをオフにすることでVDB変換と圧縮処理だけ使用する。
velをレンダリングで使用するのでResampleし、各Fieldは16bit Floatの状態のFieldを保存する。
Scatter Field
temperatureからレンダリングで使用するScatter Fieldを作成する。
temperatureを分離し、VDB ActivateでBounding Boxを拡張する。
VDB SmoothでTemperatureをぼかしたものを3つくらい用意。画像合成のグローの作り方と同じ。
VDB CombineのMaximumで3つを合体
temperatureからscatterに名前を変更。
Mergeで全部のFieldを1つにまとめる。
Sharpen Density Field
Densityとそれ以外を分離
DensityにVolume Convolveをかける
このページの処理をVolumeに対して行っている。
Volume WrangleでSharpにしたものとしていないものをScatter FieldのRangeで混ぜる。
//import field float scatter = volumesample(2, "scatter", @P); float orgDensity = volumeindex(1, "density", set(i@ix, i@iy, i@iz)); float sharpDensity = lerp(orgDensity, @density, ch("shMult")); //scatter fit range float range = fit(scatter, ch("scatOldx"), ch("scatOldy"), ch("scatNewx"), ch("scatNewy")); //Mix density @density = lerp(orgDensity, sharpDensity, range);
Shader
Density
Scatter FieldをRemapしたものをDensity FieldにMultiplyし、Pyro ShaderのDensityへつなぐ。
Emit Color
Rangeを調整してRampで色付けし、Pyro ShaderのEmit Colorへ。
Scatter Flame
Scatterにpowで1.4くらいをかけて値をしぼりつつ、それぞれをMultiplyしたのち加算する。
その後、調整したDensityをMultiplyしてPyro ShaderのEmitへつなぐ。
Ce
Densityを再度RemapしたものとCeをMultiplyして再度Ceへつなぐ