11/27 流体シミュレーション

日記

2025/11/27

今日はずっとやってみたいと思っていた、流体シミュレーションの勉強をする。

参考:https://mofu-dev.com/blog/stable-fluids/

流体シミュレーション(Stable Fluids)

リアルタイムで流体の動きをシミュレートするアルゴリズム。

1. 基本原理

流体は連続体として、ナビエ・ストークス方程式で記述されます。Stable Fluidsはこれを2Dグリッドで離散化して解きます。

連続体とは?
空間を隙間なく連続的に満たす仮想的な媒体。
例)水→液体 空気→気体 煙→連続した流体
特徴)現実では分子や粒子の集まりだが、モデルでは連続な「場」として扱う

離散化とは?
連続的な量を有限個の値で近似すること。
例)
・温度計: アナログ(0~100度まで連続)→デジタル(0.1度刻みとかで区切る)
・写真: 現実(連続的な色と形)→写真(ピクセルの集まり)
・流体シミュレーション: 分子、粒子の集まり→有限の格子

主なステップ(1フレームごと)

力の加算(Add Forces) F(Force)

マウスやキーボードなど、外部から力を加える

拡散(Diffuse) v(viscous)

速度場を拡散させる(粘性のモデル化)

投影(Project)p(pressure)

非圧縮性(質量保存)を保つために圧力を計算し、速度場を補正

移流(Advect)u

速度場に沿って密度や速度を移動させる

非圧縮性とは?
圧力がかかっても体積が変わらない(密度が一定に保たれる)性質。
空気(圧縮性あり):シリンダーで押すと、体積が減り、密度が増える
水(非圧縮性):押しても、ほとんど体積が変わらない

非圧縮性の式:∇ ・ v = 0

3. 実装に必要な要素

シェーダー(GLSL)

  • 速度場と密度場を保存するテクスチャ
  • 各種ステップ(拡散、投影、移流)を実行するフラグメントシェーダー

レンダリングターゲット(FBO: Frame Buffer Object)

  • 速度と密度の計算用に複数のバッファを使い分け(ダブルバッファ)

2Dグリッド

  • 通常は2Dテクスチャ(例: 512x512)で速度・密度を表現

インタラクション

  • マウス操作で力や密度を加える

可視化

  • 密度テクスチャをThree.jsのPlaneGeometryやMaterialで描画

偏微分とは

x,y,z上でx,yの値によってzが変わるとしたら、二次関数でいうグラフは、f(x,y)←(2変数関数)では曲面になる。山とか。

x方向とy方向では微分係数が違う。(zが上方向とする)

xの変化に対するzの変化とyの変化に対するzの変化

For in にはオブジェクト

かつて覚えていた事実がひっくり返ったんだが。

配列のLOOPで、 for-inは数字を返し、for-ofは各中身を返すから、for-inは使わないな〜て思っていたんだけど、
オブジェクトにfor-inすると、配列にfor-of使うのと同じ感じになるんだって。

しらなかた・・・

今までObject.keys(オブジェクト)で配列化してからfor-of使っていたんだけど、無駄だった(泣)

進捗

今日はずっと流体シミュレーションのやつを解析してたんだけど、全然終わらなかった。。。

マウスの動きから外圧を計算するところで今日は停止。

ずっと意味わからん事するより、もっと違う科目やる感じでいろんなことやったほうが効率いいと思うから、俺頑張れ