Lesson 10 of 10 · Forces in a shader
All together
Every force. Every shape. One piece.
This lesson teaches nothing new. It brings together every force you learned into one piece.
Look at the code, you already know every block:
- →
1.0 / (d + 0.15)tunnel, 1/distance compresses to center (Start Here 10) - →
atan() + T * 0.12spinning vortex (lesson 05) - →
sin(n * ang) * sin(m * inv)Chladni through the tunnel (Patterns 09) - →
sin(d * 15.0 - T)expanding ripple (lesson 08) - →
sin(T * 0.618)irrational breathing (lesson 04) - →
fb(p)domain warp (lesson 01)
Everything pulls toward the center. The vortex spins, Chladni draws, ripple pushes, breathing never repeats. All automatic, all alive.
Nine forces running in parallel. One single output.
Change
T*1.2 (circle pulse) to T*3. and the circle beats nervous. Change T*.3 (triangle orbit) to T*1. and it spins fast. Change length(p)*12. to length(p)*4. and the waves open up. This piece is yours.The code
void main(){
vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
float beat = pow(sin(T*1.2)*.5+.5, 4.);
// Circle, pulses
float dc = length(p-vec2(-.5,sin(T*.3)*.25))-(.18+beat*.1);
// Square, falls
float y = mod(-T*.2+1., 3.)-1.5;
vec2 sq = abs(p-vec2(0.,y))-vec2(.15);
float ds = max(sq.x,sq.y);
// Triangle, orbits
float a = T*.3;
vec2 tc = vec2(cos(a),sin(a))*.5;
float ca=cos(a*2.),sa=sin(a*2.);
vec2 tp = p-tc; tp = vec2(tp.x*ca-tp.y*sa, tp.x*sa+tp.y*ca);
vec2 at = abs(tp);
float dt = max(at.x*.866+tp.y*.5, -tp.y) - .12;
// Ripple
float ripple = sin(length(p)*12.-T*2.)*.5+.5;
ripple *= exp(-length(p)*1.2) * .2;
vec3 col = vec3(.03,.02,.06);
col += vec3(.5,.4,.7) * ripple;
col += vec3(0.,.4,.5) * exp(-max(dc,0.)*3.)*.35;
col += vec3(.0,.7,.9) * smoothstep(.02,-.02,dc);
col += vec3(.45,.15,.05) * exp(-max(ds,0.)*3.)*.35;
col += vec3(.9,.32,.1) * smoothstep(.01,-.01,ds);
col += vec3(.5,.42,.1) * exp(-max(dt,0.)*3.)*.35;
col += vec3(.95,.85,.2) * smoothstep(.01,-.01,dt);
col = hueShift(col, 0.0);
gl_FragColor = vec4(col, 1.);
}