3/3
2026/03/03
Three.js 流体
移流
uniform sampler2D uVelocityPrev; //前フレームの「投影済み速度」を読む
uniform float uDt;//0.016
uniform float uDissipation;//0.99
uniform vec2 uPointerUv; // 0..1
uniform vec2 uPointerDeltaUv; // UV delta
uniform float uPointerActive; // 0 or 1
uniform float uSplatRadius; // in cells //80
uniform float uForceStrength; //80
void main() {
vec2 uv = gl_FragCoord.xy / resolution.xy;
gl_FragColor = vec4(advect + force, 0.0, 1.0);
}まずadvectを求める。dt秒前の速度をみるセミラグランジュ法で。
vec2 fboSize = resolution.xy;
vec2 ratio = vec2(min(fboSize.x, fboSize.y)) / fboSize;
vec2 vel = texture2d(uVelocityPrev, uv).xy;
vec2 backPos = uv - uDt * vel * ratio;
backPos = clamp(backPos, vec2(0.0), vec2(1.0));
vec2 advect = texture2d(uVelocityPrev, backPos).xy * uDissipationforceは外力。マウスの位置、マウスの前の位置との差、マウスの範囲、マウスの力、マウスが動いたかどうかが与えられている。
uniform vec2 uPointerUv; // 0..1
uniform vec2 uPointerDeltaUv; // UV delta
uniform float uPointerActive; // 0 or 1
uniform float uSplatRadius; // in cells //80
uniform float uForceStrength; //80vec2 radiusUv = uSplatRadius / resolution.xy * 0.5
vec2 centerUv = clamp(uPointerUv, radiusUv, 1.0 - radiusUv);
vec2 circle = (uv - centerUv) / radiusUv; //centerUvからの距離をradiusUvで正規化する。centerUvから数値があがり、半径ちょうどのところが1となり、それより外は上がっていく。
float d = 1.0 - min(length(circle), 1.0); // 中央が1、半径で0となる
d *= d;
vec2 force = d * uPointerActive * uForceStrength * uPointerDeltaUv;radiusUvで割るところ。半径の部分で1になってやりやすくなるのが計算の工夫っぽくてよい。
また、uPointerActiveではboolではなく01で渡すことによって計算が容易になるのか。
なんとか理解。次はdivergence(発散)
内省
マクドがどうしても食べたくなって、食べに行ったが、770円する割に量が少なく感じた。自炊し始めてから色々もったいなく感じる。
Since I started cooking for myself, I've started feeling wasteful about all sorts of things.