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

Phase offset

Each diamond starts on its own time. The wave.

Until now the whole canvas moves at the same time. What you want is for each element to start at a different moment.

The code has seven diamonds in a loop. Each one adds its index fi * 0.9 inside the sin(): sin(T * 2.5 + fi * 0.9). The first diamond reaches its peak before the second, the second before the third, the wave runs down the row.

Each point starts on its own timeline. The wave propagates.

Phase offsetThe term you add inside sin() alongside T. If it is fi * 0.9, the wave travels through the loop. If it were p.x * 2., it would travel through space. If it were length(p) * 4., it would expand in circles.
TryChange 0.9 (offset between diamonds) to 0. and they all rise at the same time, the wave disappears. To 3.14 and diamonds alternate even/odd. Change 2.5 (speed) to 0.8 for a lazy wave.

The code

void main(){
  vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
  vec3 col = vec3(0.03, 0.01, 0.04);
  for(int i = 0; i < 7; i++){
    float fi = float(i);
    float x = -0.9 + fi * 0.3;
    float y = sin(T * 2.5 + fi * 0.9) * 0.35;
    vec2 q = abs(p - vec2(x, y));
    float d = q.x + q.y - 0.1;
    vec2 qs = abs(p - vec2(x, y) + vec2(.03,-.05));
    col *= smoothstep(-.02, .12, qs.x+qs.y-0.1);
    col += vec3(.95,.25,.55) * smoothstep(.01,-.01, d);
  }
  gl_FragColor = vec4(col, 1.);
}
close