learn GLSL from zero
ToolsCreate with shadersShader MakerFree online shader builderToolkitShader works ready for your siteSketcher LabPaint your landing’s hero with shaders3D StudioThe Three.js editor in your browser
GamesPlay with shadersOnomatoShaderType a word, blow it upThe WatcherAn eye that follows youAetherLiquid glass with an eye insideBloomcoreA word grows a garden of lightPyrokineThrow fire at the wallVoltaicThe pyramid throws lightningSurfSurf a shader ocean

Lesson 1 of 10 · Forces in a shader

Forces

Three shapes. Zero forces. The before.

Look at what you already know how to build. Stripes, spirals, radials, Chladni, patterns, all with code you wrote. That is not beginner work. That is real.

What is missing is motion. Still images are posters. Moving images are alive.

Static frame = poster. Animated frame = living system.

Before moving them you need a material, something with irregular texture that feels natural when you push it. fb() is that function: it generates fields with detail at every scale. For now it is a black box, in the next section you will learn what is inside. Here you use it as a tool.

This section teaches you 9 forces:

fb(p)fb() generates irregular texture, like clouds, smoke, terrain. It is your base material. Each lesson adds ONE force to move it.
TryThe three shapes barely move, a subtle up-and-down bob. Change 0.02 to 0.0 and they freeze. To 0.1 and they float. But this is still the before, in Gravity you add a real force.

The code

void main(){
  vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
  float b = sin(T*.8)*.02;
  vec3 col = vec3(0.03, 0.02, 0.08);
  // Circle
  float dc = length(p-vec2(-.55,b))-.25;
  col *= smoothstep(-.02,.2,length(p-vec2(-.48,b-.08))-.25);
  col += vec3(0.0,0.7,0.9) * smoothstep(.02,-.02,dc);
  col += vec3(0.0,0.35,0.45) * exp(-max(dc,0.)*4.)*.4;
  // Square
  vec2 sq = abs(p-vec2(0.,-b))-vec2(.18);
  float ds = max(sq.x,sq.y);
  vec2 ssq = abs(p-vec2(.06,-.08-b))-vec2(.18);
  col *= smoothstep(-.02,.2,max(ssq.x,ssq.y));
  col += vec3(.9,.3,.1) * smoothstep(.01,-.01,ds);
  col += vec3(.45,.15,.05) * exp(-max(ds,0.)*4.)*.4;
  // Triangle
  vec2 tp = p-vec2(.55,-b); vec2 at = abs(tp);
  float dt = max(at.x*.866+tp.y*.5,-tp.y)-.22;
  vec2 st = abs(tp+vec2(.05,-.06));
  col *= smoothstep(-.02,.15,max(st.x*.866+(tp.y-.06)*.5,-(tp.y-.06))-.22);
  col += vec3(.95,.85,.2) * smoothstep(.01,-.01,dt);
  col += vec3(.5,.42,.1) * exp(-max(dt,0.)*4.)*.4;
  col = hueShift(col, 0.0);
  gl_FragColor = vec4(col, 1.);
}
close