Lesson 6 of 10 · Shader animation
Flow field
Each triangle spins at its own speed. Every corner its own law.
Until now time advances equally everywhere. But in a river, there are fast zones and stagnant zones. That is a flow field.
The trick: instead of adding T directly, multiply it by a value that changes with position. T * (0.5 + fb(p)). Where noise is high, time runs fast. Where low, it nearly stops.
Every coordinate has its own velocity.
Flow fieldA field where each point has its own velocity. You modulate
T with a spatial function. The result: motion that feels liquid.Change
0.3 (base speed) to 0. and the slowest cells freeze. Change 1.5 (range between fast and slow) to 4. and the gap between cells goes extreme. To 0. and they all spin at the same pace.The code
void main(){
vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
vec3 col = vec3(0.03, 0.02, 0.01);
for(int j = 0; j < 3; j++){
for(int i = 0; i < 3; i++){
float fi=float(i), fj=float(j);
vec2 c = vec2(-0.6+fi*0.6, -0.6+fj*0.6);
float vel = 0.3 + n2(c+1.) * 1.5;
float ang = T * vel;
float ca=cos(ang), sa=sin(ang);
vec2 q = p-c; q = vec2(q.x*ca-q.y*sa, q.x*sa+q.y*ca);
vec2 aq = abs(q);
float d = max(aq.x*.866+q.y*.5, -q.y) - 0.14;
vec2 sq=q+vec2(.04,-.06); vec2 asq=abs(sq);
col *= smoothstep(-.02,.12,max(asq.x*.866+sq.y*.5,-sq.y)-.14);
float bright = .45+vel*.35;
col += vec3(.95,.7,.15) * smoothstep(.01,-.01,d) * bright;
col += vec3(.5,.35,.08) * exp(-max(d,0.)*5.) * vel * .25;
}
}
gl_FragColor = vec4(col, 1.);
}