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 2 of 10 · Shader animation

Drift layers

Four planes at different speeds. Geometric depth.

A single object moving feels flat. Five layers at different speeds create the illusion of depth, like fence posts seen from a car: the far ones crawl, the near ones fly past.

The trick: five squares, each with its own velocity 0.04 + fi * 0.06. The first barely moves, the last crosses the screen. Your brain reads speed as distance.

Slow in back, fast in front. Parallax in 2D.

Velocity parallaxMultiple layers at different speeds produce depth without a 3D camera. Each square enters the loop with its fi and gets its own spd.
TryChange 0.04 (base speed) to 0.0 and the first square freezes at the back. Change 0.06 (per-layer increment) to 0.2 and the gap between far and near goes extreme. To 0. and they all move identically, depth collapses.

The code

void main(){
  vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
  vec3 col = vec3(0.02, 0.02, 0.05);
  for(int i = 0; i < 5; i++){
    float fi = float(i);
    float spd = 0.04 + fi * 0.06;
    vec2 c = vec2(sin(T*spd+fi*2.2)*.8, cos(T*spd*.5+fi*1.8)*.6);
    vec2 sz = vec2(.12+fi*.03, .07+fi*.02);
    vec2 qs = abs(p-c+vec2(.06,-.08))-sz;
    col *= smoothstep(-.02,.2,max(qs.x,qs.y));
    vec2 q = abs(p-c)-sz;
    float d = max(q.x, q.y);
    float alpha = .45+fi*.15;
    col += vec3(.1+fi*.2,.18+fi*.14,.8-fi*.12) * smoothstep(.01,-.01,d) * alpha;
    col += vec3(.05+fi*.1,.1+fi*.07,.4-fi*.06) * exp(-max(d,0.)*4.) * .2;
  }
  col = hueShift(col, 0.0);
  gl_FragColor = vec4(col, 1.);
}
close