Animating with Time
by GameDev.net · GLSL ES 3.00 (WebGL2) · 25 Aug 2026
Run the shader to adjust these controls.
What it demonstrates
This shader introduces iTime as a continuously changing input. It animates a sine wave across the viewport while exposing independent Speed and Amplitude sliders. The result shows how time changes phase, position changes the waveform across space, and a distance field gives that moving curve visible thickness.
Shader inputs
void mainImage(out vec4 fragColor, in vec2 fragCoord)
Called once per pixel. Write the colour to fragColor.
-
iResolutionvec3 - Viewport size in pixels (z is the pixel aspect ratio).
-
iTimefloat - Seconds since the shader started.
-
iTimeDeltafloat - Seconds since the previous frame.
-
iFrameRatefloat - Frames per second, smoothed.
-
iFrameint - Frames rendered since the start.
-
iMousevec4 - Mouse position: xy while held, zw of the last click.
-
iDatevec4 - Year, month, day, and seconds within the day.
-
iChannel0sampler2D - Texture bound to channel 0.
-
iChannel1sampler2D - Texture bound to channel 1.
-
iChannel2sampler2D - Texture bound to channel 2.
-
iChannel3sampler2D - Texture bound to channel 3.
-
iChannelResolutionvec3[4] - Pixel size of each bound channel texture.
-
iChannelTimefloat[4] - Playback time of each channel, in seconds.
-
iSampleRatefloat - Audio sample rate, always 44100.
Main Image5
uniform float uSpeed; // @param 0.0..4.0 = 1.0 "Speed"
uniform float uAmplitude; // @param 0.0..0.45 = 0.22 "Amplitude"
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord / iResolution.xy;
float phase = iTime * uSpeed;
float wave = sin(phase + uv.x * 6.2831853);
float centerLine = 0.5 + wave * uAmplitude;
float distanceToLine = abs(uv.y - centerLine);
float stroke = 1.0 - smoothstep(0.012, 0.025, distanceToLine);
vec3 color = mix(vec3(0.025, 0.04, 0.09), vec3(0.20, 0.90, 0.72), stroke);
fragColor = vec4(color, 1.0);
}
Learn from this shader
How it works
ShaderLab supplies elapsed seconds in iTime. Multiplying time by Speed creates a phase that advances faster or slower without changing the curve's shape. Horizontal UV position is scaled by one full turn and added to that phase before calling sin. The resulting value ranges from negative one to one. Amplitude scales it, and adding one half places the wave around the screen center. For every pixel, the absolute vertical distance to that center line is measured. smoothstep converts a narrow distance range into a soft stroke mask used to blend foreground and background colors.
Try changing
Set Speed to zero to freeze the wave, then adjust Amplitude. Compare low and high speed without changing the spatial wavelength. In a fork, subtract phase instead of adding it to reverse travel, multiply uv.x by two full turns for two waves, or replace sin with cos and observe that only the starting phase changes.
Using it in a game
Time-driven waves can animate energy bars, force fields, water accents, and UI highlights. In an engine, use its time uniform and consider pause state, time scaling, and deterministic replay requirements. This full-screen example is opaque, but the stroke mask could drive emission or alpha in a material.
Explore the techniques
Continue with curated explanations and progressively related examples.
Discussion