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 8 of 10 · Noise in GLSL

Color shift

The field gets its coating.

Until now every pixel painted a single color. Now you compute the pattern three times, once per RGB channel, and shift the coordinates a little between them. Red does not land where blue lands.

That is chromatic aberration: the signal splits into its primaries. The classic broken-TV or cheap-lens effect.

Chromatic aberration. The broken screen you find beautiful.

Three samples, one offsetThe same step+sin math runs three times. One uses p + shift for red, another uses p for green, another uses p - shift for blue. The shift breathes with sin(T).
TryChange 0.06 (base shift) to 0.0 and the signal snaps back together. To 0.2 and aberration goes psychedelic. Change 0.5 (breathe speed) to 2. and the effect accelerates.

The code

void main(){
  vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
  float shift = 0.06 + 0.03 * sin(T * 0.5);
  float scan = step(0.5, sin(gl_FragCoord.y * 2.0) * 0.5 + 0.5) * 0.08;
  vec2 pr = p + vec2(shift, 0.0);
  vec2 pb = p - vec2(shift, 0.0);
  float r = step(0.5, sin(pr.x * 15.0 + n2(vec2(pr.y * 3.0, 1.0)) * 4.0) * 0.5 + 0.5);
  float g = step(0.5, sin(p.x * 15.0 + n2(vec2(p.y * 3.0, 2.0)) * 4.0) * 0.5 + 0.5);
  float b = step(0.5, sin(pb.x * 15.0 + n2(vec2(pb.y * 3.0, 3.0)) * 4.0) * 0.5 + 0.5);
  vec3 col = vec3(r * 0.85, g * 0.9, b * 0.75);
  col *= 1.0 - scan;
  col += vec3(0.02);
  col = hueShift(col, 0.0);
  gl_FragColor = vec4(col, 1.);
}
close