流体エフェクトシステム β版概要(追記予定)

流体システム ユーザーマニュアル

本ドキュメントでは、このプロジェクトに実装されている「流体シミュレーションシステム」の全体像と、各ノードの使い方・設定項目を説明します。
パーティクルでは表現不可能なシームレスな軌跡などが表現可能になります。

サンプルプロジェクト
下記のサンプルエフェクトはすべてサンプルプロジェクトに入っております。
F5でgame_sceneを実行後、
ZXCV ASDF QWE に各種エフェクトが割り当てられており、player.tscnのvsで割り当てをご確認いただけます。

スクリプトのみ
fluid_simulation_core.zip (71.2 KB)

flame_trail

frost_ball

frost_effect

lightning_strike

poison_tentacle

poison_tentacle_hit

spin_weapon

wind_spell

crystal_spear

dark_spell

fire_ball

flame_spear

  • FluidBufferPool(Autoload): GPUのバッファを使い回してパフォーマンスを維持する内部システムです。シーンに直接置く必要はありません。
  • 流体シェーダー群shaders/fluid/ 内): 実際の流体計算をGPUで行うシェーダーファイルです。編集は不要です。

ノード①:FluidSimulationController

役割

流体シミュレーション全体の「心臓部」です。GPUバッファの確保・流体計算・画面への描画まで、すべてを管理します。シーンに 必ず1つ 配置してください。

注意: 1シーンに複数置くとバッファが台数分確保されVRAMを圧迫します。

主要な設定項目

基本設定

項目 説明 デフォルト
auto_fit_to_window シミュレーション領域をウィンドウサイズに自動で合わせます。ONにするとウィンドウリサイズ時に全バッファが再確保されスパイクが発生します。 OFF
use_deferred_init 初期化を次フレームに遅らせます。ONにするとinstantiate直後の1フレームは描画されません_ready()内でテクスチャを参照しても空です。 ON
texture_size auto_fit_to_windowがOFFの場合の固定解像度です。 768×512
sim_area_size auto_fit_to_windowがOFFの場合に、流体がカバーするワールド空間のサイズ(ピクセル)を固定します。(0,0)の場合はtexture_sizeと同じ。未設定のままtexture_sizeを変更するとFluidEffectNodeのUV位置がズレます。 (0, 0)

パフォーマンス / 品質

項目 説明 デフォルト
simulation_scale 解像度のスケール。1.0が最高品質ですが最も重い。0.5が推奨です。 0.5
pressure_iterations 流体の圧力計算の精度。多いほど綺麗ですがGPU負荷が上がります。10程度が目安です。 10
path_bake_resolution Pathモードの効果ノード用の方向テクスチャ解像度(8〜64)。小さいほど高速。 16
path_bake_sample_density Pathモードのカーブ点1個あたりのサンプル数(1〜8)。 4

動作設定

項目 説明 デフォルト
simulation_active OFFにすると計算を完全停止します。見た目はそのまま維持されます。 ON
auto_sleep_enabled インクと入力が途絶えたあと、自動で計算を停止します。パフォーマンス節約に有効です。 ON

ビジュアルと発光

項目 説明 デフォルト
dye_brightness インク全体の明るさ倍率です。 1.0
dye_glow_mode 発光スタイルです。「標準発光」と「染料発光」の2種類があります。 標準発光
dye_glow_boost 発光の強さです。上げるほど光って見えます。 0.0
dye_base_ink_opacity インクの不透明度です。0にすると発光成分のみが見えます。 1.0
dye_alpha_gain 全体の不透明度の増幅倍率。インクをさらに濃く見せたい場合に使用します。 1.0
dye_velocity_visibility_scale 「染料発光」モード限定。dye_base_ink_opacityが1未満の時、流体の速度が高い場所だけインクの不透明度を上げる強さです。大きくするほど弱い移動でもインクがくっきり現れます。 40.0
dye_color_variation_strength 時間経過で色相が揺らぐ強さです。0で無効。 0.0
dye_color_variation_speed 色相の揺らぎが変化する速度です。 1.3
dye_glow_pulse_strength グローが脈打つように明滅する強さです。0で無効。 0.0
dye_glow_pulse_speed 明滅の速度です。 1.6
dye_alpha_cutoff この値未満のアルファは完全透明にカットします。ゴミピクセルを防ぎます。 0.04

インクの消滅設定

項目 説明 デフォルト
dye_evaporation インクが時間で徐々に薄まる速度です。 (設定値による)
dye_hard_clear_threshold インクがこの密度を下回ったら即座に消去します。 0.06
decay_distance_factor 移動距離に応じて消滅を早める係数。先端からスッと消えます。0で無効。 0.0
decay_velocity_factor 速度に応じて消滅を早める係数。勢いよく飛んだインクが散ります。0で無効。 0.0

流体物理設定

項目 説明 デフォルト
viscosity 粘り気。高いほどドロッとした流体になります。 0.18
curl_strength 渦の補強の強さ。高いほど複雑な渦巻きが生まれます。 28.0
curl_idle_scale 入力がない時に渦をどれだけ維持するか(0.0〜1.0)。 0.08
idle_velocity_damping 入力がない時の流れのフェードアウト率。1.0で減衰なし。 0.975
max_velocity 流れの速度の上限値。 2.4
velocity_floor この値未満の速度は強制的にゼロとみなします。計算の安定性向上に使います。 0.006
pressure_dissipation 圧力の減衰率。下げると反発が弱まります。 0.999

速度加算の詳細制御

通常は変更不要です。ブラシの追従感やスプレーの勢いを細かく調整したい場合に使います。

項目 説明 デフォルト
input_velocity_cap_scale ブラシ移動時のインク速度の上限倍率。高くするとブラシへの追従が速くなりますが固まりやすくなります。 10.0
input_velocity_add_scale ブラシ移動時のインク速度加算の基本倍率。 1.0
outflow_velocity_cap_scale スプレー・吹き出し時のインク速度の上限倍率。 2.5
outflow_velocity_add_scale スプレー・吹き出し時のインク速度加算の基本倍率。 0.8

ノード②:FluidBrushNode

役割

流体の「インク」を注入するノードです。位置・形状・色・強度などを設定します。FluidSimulationController兄弟ノード(同じ親の下)として配置します。1つのシミュレーションに複数置けます。

注意: FSCの子や孫に置いても認識されません。必ず同じ親の下(兄弟)に置いてください。

主要な設定項目

基本設定

項目 説明 デフォルト
emit_mode インクを注入する位置の決め方です。Mouse: マウスポインタの位置 / NodeCenter: このノード自身の位置 / TargetNode: 別ノードの位置に追従 Mouse
emit_trigger 注入するタイミングです。Click: クリック時のみ / Always: 常時注入(静止中もインクが出続けます) / Signal: emit_once()を呼んだときのみ Always
emit_target_path TargetNodeモード時に追従するノードのパスです。 -

ブラシ形状

項目 説明 デフォルト
brush_shape ブラシの基本的な形状です。Circle: 円形 / Ellipse: 楕円形 / Texture: 指定したテクスチャの形状 / GlobalTexture: 別途指定したViewport全体の画像をブラシにします / NodeCapture: 指定した別ノードのビジュアルをコピーしてブラシにします Circle
brush_texture TextureまたはEllipseモード時にブラシの形として使用するテクスチャです。 -

GlobalTexture専用

項目 説明
global_texture_viewport_path キャプチャするSubViewportのパスです(ゲーム実行時に自動解決されます)。
global_texture_include_hidden 非表示ノードもキャプチャに含めるかどうかです。
global_texture_use_content_motion Viewport内の動きを流体への力として流し込むかどうかです。

NodeCapture専用

項目 説明
target_node_include_hidden 対象ノードが非表示でもキャプチャして流体に反映するかどうかです。
target_node_respect_clip ソースノードの祖先にclip_childrenが設定されている場合にそのクリップ境界を再現するかどうかです。falseの場合はノード全体をキャプチャします。

ブラシ変形・角度

項目 説明 デフォルト
input_radius ブラシの半径(シミュレーション全体の解像度に対する相対比率、0.0〜1.0)です。 0.035
brush_texture_size_mode テクスチャブラシの解像度決定モードです。Radius: input_radiusの比率からサイズを決定します / OriginalPixels: 元テクスチャのピクセル寸法そのままで描画します Radius
brush_texture_pixel_scale OriginalPixelsモード時の追加倍率(1.0で等倍)です。 1.0
brush_texture_rotation_degrees ブラシ(テクスチャ)の基本的な回転角(度)です。 0.0
brush_rotation_source ブラシ回転角の基準をどこから取得するかです。Fixed: 上記の基本回転角のみ / ThisNode: このノード自身のrotationを加算 / NodeCapture: 追従対象ノードのrotationを加算 / RotationNode: 下記の指定ノードからrotationを加算 Fixed
brush_rotation_node_path RotationNodeモード時に参照する回転角ノードのパスです。 -
pivot_follow_visual_center NodeCaptureモード時に、対象ノードのスプライトオフセットなどビジュアル上の中心を基準に追従させるかどうかです。ONにすると回転時にUVが適切に連動します。 OFF
brush_flip_h ブラシテクスチャを左右反転します。 OFF
brush_flip_v ブラシテクスチャを上下反転します。 OFF

ブラシマスク

ブラシのどの部分を「有効」とするかをテクスチャ情報でフィルタリングします。

項目 説明 デフォルト
brush_mask_source マスクの判定に使う情報の種類です。Alpha: アルファ値 / Luminance: 輝度 / Color Range: 指定色との近さ / Saturation: 彩度 Alpha
mask_invert マスクを反転します(白黒が逆転します)。 OFF
mask_threshold この値未満の薄いマスクは完全に透明として扱います(全モード共通)。 0.0
mask_softness マスクの境界部分の滑らかさです。0でくっきり、1で滑らかにフェードします(全モード共通)。 0.1
mask_target_color Color Rangeモード時のくり抜き基準色です。
mask_color_tolerance Color Range限定。ターゲットカラーからどのくらいずれた色まで許容するか(小さいほど厳密)です。 0.3

色・スタンプ

項目 説明 デフォルト
emit_dye 染料(インク画像)を注入するかどうかです。falseにすると「流体を動かす力(Force)」だけを発生させる透明なブラシになります。 ON
inject_color_mode 注入する色の決定方法です。Solid: 単色(input_colorを使用) / Gradient: グラデーションテクスチャを適用 / BrushTexture: ブラシテクスチャ自体の色をそのまま使用 Solid
input_color 注入する染料のベースカラーです。 青みがかった白
inject_strength 一回の注入スタンプの「濃さ」です。高いほど色がはっきりと強く乗ります。 1.0
uniform_paint ブラシ形状のアルファグラデーションを無視して、ブラシ内をinject_strengthで均一塗りにします。BrushTextureモードでは色も均一(白)になります。 OFF
inject_blend 既存の染料とのブレンド方法です。0.0で完全な上書き、1.0で完全な加算(色が白く飛ぶ)になります。 0.35
edge_hardness ブラシ外側のエッジのくっきり度です。数値が高いほど境界が鋭くなります。 1.25
ink_edge_bleed 既存インクの上に重ねて描く際、新インクのエッジをにじませる強さです。0.0=なし、1.0=最大。既存インクがない場所には影響しません。 0.0

グラデーション専用inject_color_modeGradientの場合のみ有効)

項目 説明 デフォルト
gradient_mode グラデーションの適用形状です。Radial(放射状)またはLinear(線形)です。 Radial
gradient_texture グラデーションに使用するテクスチャ(ColorRamp画像など)です。 -
gradient_rotation_degrees グラデーションの基準となる回転角(度)です。 0.0
gradient_rotation_source グラデーション回転角の取得元です(brush_rotation_sourceと同様の選択肢)。 Fixed
gradient_rotation_node_path RotationNodeを選んだ場合に参照するパスです。 -

移動・力

項目 説明 デフォルト
force_scale ブラシの移動量を流体を動かすForceに変換する倍率です。高いほどブラシを動かした時に流体が強く引っ張られます。 85.0
spread_force_reference ブラシ入力による速度が強いほどインクが広がる補正の基準値です。0の場合はspray_force_limitを基準に自動計算されます。 0.0
spread_force_to_advection_scale Forceに応じて染料の移流(流れる動き)を広がりやすくする倍率です。大きくすると筆を速く動かした時にインクがより大きく散ります。0.0で無効。 1.0
spread_force_to_diffusion_scale Forceに応じて染料の拡散(滲み)を強める倍率です。大きくすると筆を速く動かした時にインクがぼやけやすくなります。0.0で無効。 0.0

噴射・スプレー

項目 説明 デフォルト
spray_direction_mode 噴射の方向の決め方です。Motion: マウスやノードの進行方向 / Fixed: 下記の固定ベクトル / ToTarget: 特定のノードへ向けて / Velocity: ノードの移動速度から算出した方向 Motion
spray_profile 噴射の形状です。Cone: 扇形に広がる / Parallel: 平行に直進する Cone
spray_fixed_direction Fixedモード時の固定ベクトルです。 右向き
spray_target_path ToTargetモード時に向かう対象ノードのパスです。 -
spray_spread_degrees Coneの場合の広がる角度(度)です。180で全方位(円)になります。 85.0
spray_force 噴射の基本の強さです。0にすると進行方向へのスプレー効果は発生しません(単純な移動追従のみ)。 0.0
spray_force_limit 噴射の力の上限値です。流体が破綻するのを防ぎます。 0.25
spray_outflow_strength ブラシの中心から外側へ向かう放射状の力の強さです。 0.0
spray_velocity_scale ノード自身の移動速度を噴射力にどれくらい上乗せするかです。1.0で完全に乗算。 0.0
spray_keep_last_direction_when_idle MotionまたはVelocityモード時に、移動が止まっても最後の噴射方向を維持してスプレーし続けるかどうかです。 ON

連続描画

項目 説明 デフォルト
continuous_ink_mode マウスを速く動かした時や、ノードが高速で移動した時に、ブラシの軌跡の間を滑らかに補間して描画します。OFFにするとスタンプが点々と並んだ軌跡になります。 ON
continuous_ink_quality 補間の品質(分割ステップ数)です。高いほど滑らかになりますがGPU負荷が上昇します。150〜200程度が推奨です。大きすぎると高速移動時に1フレームで大量スプラットが走りGPUが詰まります。 150
interpolate_rotation TargetNodeなどで回転角や拡大率が変わった際、その変化も軌跡に沿って滑らかに補間するかどうかです。 OFF
spray_use_direction_sweep 連続描画中に噴射方向を軌跡に沿ってスイープするかどうかです。 OFF

物理・減衰

これらはFluidSimulationControllerの対応するパラメータをこのブラシからの注入時のみ上書きします。ブラシごとに異なる消え方をさせたい場合に使います。

項目 説明 デフォルト
velocity_dissipation 速度場(流れる力)の減衰フレームレートです。1.0で減衰なし、低いほどすぐに水流が止まります。 0.995
dye_dissipation 染料(インク画像)のフェードアウト率です。1.0で減衰なし、低いほどインクがすぐ薄くなります。 0.985
dye_evaporation 毎フレームこの値だけ強制的にインクの濃度を削ります。水滴などがスッと消える表現に使います。 0.12
dye_diffusion 染料の拡散(滲み)の強さです。高いほど水に溶けるようにインクの輪郭が周囲にぼやけて広がります。 0.06

ノード③:FluidEffectNode

役割

流体に「力」を加えるノードです。吸い込み・吹き出し・渦などの効果を範囲で指定できます。FluidSimulationController兄弟ノードとして配置します。

範囲の設定方法: このノードの子としてCollisionShape2Dを追加し、そこにCircle / Rectangle / CapsuleのShapeをセットしてください。インスペクターの「Add Collision Shape」にチェックを入れると半径50のCircleShape2Dで自動作成されます。CollisionShape2Dが存在しない場合(PathモードとTextureモードを除く)は効果が出ません。

主要な設定項目

力の設定

項目 説明 デフォルト
direction 力の向きです。-1.0: 中心へ吸い込む / 1.0: 中心から吹き出す -1.0(吸い込み)
force_mode 力の適用モードです。Radial: 中心から放射状 / Direction: 指定した一方向 / Path: Path2Dに沿って流れる / Texture: テクスチャの勾配方向に力をかける Radial
direction_vector Directionモード時の力の向き(方向ベクトル)です。 上向き
path Pathモード時に使用するPath2Dのパスです。 -

強さ

項目 説明 デフォルト
strength 力の強さです。 1.0
strength_gradient 中心から端にかけての強度グラデーションです。未設定で均一になります。 -

渦設定

項目 説明 デフォルト
vortex_strength 渦の強さです。0で無効。 0.0
vortex_direction 渦の回転方向です。1=反時計回り、-1=時計回り。 1.0
pure_vortex ONにすると中心方向の力をゼロにして、渦だけを適用します。 OFF

表示設定

項目 説明 デフォルト
enabled OFFにするとこのノードの効果を無効にします。 ON

ノード④:GroupNoiseCaptureViewport

役割

指定したグループに属するノード(キャラクターのスプライトなど)の「シルエット」を取得し、それをノイズで削ったテクスチャを生成します。生成したテクスチャをFluidBrushNodebrush_textureに渡すことで、「キャラクターの形に沿ってインクが注入される」表現が実現できます。

炎が体の形に燃え上がるような表現に使います。

セットアップ方法

  1. シーンにGroupNoiseCaptureViewportノードを配置します。

  2. インスペクターの「[Editor] 子ノード一式をセットアップ」ボタンをクリックします。自動的に必要な子ノードが作られます。

  3. target_groupに、キャプチャしたいノードのグループ名を入力します(例: "fluid_capture")。

  4. キャプチャ対象のスプライトノードをそのグループに追加します。

  5. 同じシーン内のFluidBrushNodebrush_shapeGlobalTextureに、global_texture_viewport_pathをこのノードのFinalLayerに設定します。MaskLayerを指定しても色情報がないため真っ白になります。

主要な設定項目

キャプチャ設定

項目 説明 デフォルト
target_group キャプチャするノードのグループ名です。 “fluid_capture”
local_scene_only 同じシーン(インスタンス)内のノードのみをキャプチャします。OFFにするとシーンをまたいで同グループのノードをキャプチャできます。別シーンのスプライトにエフェクトを乗せたい場合に使います。 ON
update_mode 更新タイミングです。Always: 毎フレーム更新 / Manual: refresh_capture()を呼んだときのみ Always
capture_size キャプチャするサイズ(ピクセル)です。 自動(流体シミュレーションに合わせる)
auto_align_to_fluid_simulation 流体シミュレーションの領域に自動でカメラとサイズを合わせます。ONを推奨します。 ON
pool_subviewports SubViewportをプールして再生成スパイクを抑制します。頻繁に生成・破棄されるエフェクトに使います。常駐するシーン(ステージに置きっぱなしのもの)でONにしても意味がありません。 OFF

ノイズマスク設定

項目 説明 デフォルト
noise_texture シルエットを削るためのノイズテクスチャです。炎っぽい凸凹形状を作ります。 -
tint_color 出力テクスチャの色の乗算値です。
noise_threshold ノイズのしきい値。この値より暗い部分が削られます。大きくするほどシルエットが削れます。 0.5
noise_edge_hardness 境界のハードさです。1.0に近いほどクッキリした境界になります。 0.1
noise_scroll_speed ノイズをスクロールさせる速度。炎が揺れる動きを作ります。 (0, -0.5)
noise_scale ノイズのUVスケールです。大きくするほど模様が細かくなります。 1.0

パフォーマンス最適化について

FluidBufferPool(Autoload)

仕組み

このシステムはGPUのSubViewportを大量に使います。通常、ノードが生成されるたびにGPUバッファを確保するとカクつきが発生します。

FluidBufferPoolはAutoloadとして常駐し、一度確保したGPUバッファを子ノードとして保持したまま使い回すことで、2回目以降の生成コストをゼロにします。エフェクトシーンがツリーから外れても、バッファはPoolの中に残り続けます。次に同じサイズ・反復回数のエフェクトが生成された時に、既存のバッファがそのまま渡されます。

1つのFluidSimulationControllerが必要とするバッファ一式をBufferSetと呼びます。PoolはBufferSetを「使用中 / 空き」のフラグで管理しています。

  • acquire(): 空きBufferSetがあれば返します。なければ新規生成します。

  • release(): BufferSetを「空き」に戻します。queue_free()はしません。

  • prewarm(): 指定したサイズのBufferSetを事前に空きとして生成しておきます。

Autoloadなしでも動く

FluidBufferPoolがAutoloadとして存在しない場合、各FluidSimulationControllerGroupNoiseCaptureViewportは自分の子ノードとしてSubViewportを生成するフォールバック動作に切り替わります。パフォーマンスは落ちますが動作自体は問題ありません。

設定項目

項目 説明
pool_enabled falseにするとプールを完全無効化します。acquire()が毎回新規生成し、release()が即queue_free()します。プールの効果を計測する際のベースライン測定用です。
auto_scan_dirs 起動時に自動スキャンするディレクトリ一覧(res://相対パス)です。デフォルトは["res://effects/"]。ここに含まれる.tscnファイルを再帰的にスキャンしてprewarm_from_scene()を自動実行します。
prewarm_scenes 事前確保したいエフェクトシーン(PackedScene)を手動で登録します。
prewarm_count 各シーンを何セット分確保するか。同時に複数使う場合は増やします。

Prewarm(事前ウォームアップ)の詳細

prewarm_from_scene(scene, count)

PackedSceneを解析して、含まれるFluidSimulationControllerGroupNoiseCaptureViewportの設定を自動検出し、必要なバッファを事前生成します。auto_fit_to_windowがONのシーンは現在のウィンドウサイズから計算されます。ウィンドウサイズが確定する前(_ready()の早い段階など)に呼ぶと正しいサイズで確保されません。

GroupNoiseCaptureViewportpool_subviewportsがOFFのものはスキャンをスキップします。auto_align_to_fluid_simulationがONのものは、直前に検出したFluidSimulationControllerのサイズに自動で合わせます。

prewarm_gncv(size, group, count)

GroupNoiseCaptureViewport用のSubViewportペア(MaskLayerとFinalLayer)を事前生成します。prewarm_from_scene内から自動呼び出しされます。

プール容量の上限

定数 説明
MAX_FREE_PER_KEY 8 同一サイズ・反復回数の空きBufferSet保持上限
MAX_FREE_TOTAL 100 全キー合計の空きBufferSet保持上限

上限を超えた空きBufferSetはqueue_free()されます。