Home / Guides / Custom Shaders

Custom Shaders

The Custom Shader allows advanced users to write their own GLSL fragment shader code, enabling complete creative freedom to design unique visuals that react to your music. This feature is for users who are comfortable with shader programming.

Getting Started

Select Custom from the shader gallery. You'll see a code editor where you can write your GLSL code.

How It Works

You write a complete GLSL fragment shader with a main() function. The template provides uniforms, coordinates, and helper functions - you just need to write main() and any custom functions you need.

void main() {
  vec3 color = mix(iStartColor, iEndColor, vUv.x);
  gl_FragColor = vec4(color, 1.0);
}

You can also define your own helper functions:

float circle(vec2 uv, vec2 center, float radius) {
  return smoothstep(radius, radius - 0.01, length(uv - center));
}

void main() {
  float c = circle(vUv, vec2(0.5), 0.3);
  gl_FragColor = vec4(mix(iStartColor, iEndColor, c), 1.0);
}

Available Uniforms

Time & Audio

UniformTypeDescription
iGlobalTimefloatTime in seconds since start
iBpmfloatBeats per minute of the audio
iLowFreqfloatLow frequency intensity (0-1)
iMidFreqfloatMid frequency intensity (0-1)
iHighFreqfloatHigh frequency intensity (0-1)
iSoundTexturesampler2DFull audio spectrum texture

Custom Parameters

These parameters appear in the UI and can be bound to audio reactivity:

UniformTypeDescription
iStartColorvec3Start color (RGB, 0-1 range)
iEndColorvec3End color (RGB, 0-1 range)
iIntensityfloatIntensity parameter (0-10)
iPatternfloatPattern parameter (0-10)

Coordinates

NameTypeDescription
vUvvec2UV coordinates (0-1 range)
iResolutionvec2Resolution (1920x1080)
PIfloat3.141592654
TAUfloat2 * PI

Helper Functions

map(value, min1, max1, min2, max2)

Maps a value from one range to another.

float normalized = map(value, 0.0, 100.0, 0.0, 1.0);

getFrequency(x)

Gets the audio frequency at position x (0-1 range) from the sound texture.

float bass = getFrequency(0.1);  // Low frequencies
float treble = getFrequency(0.9); // High frequencies

Examples

Simple Gradient

void main() {
  vec3 color = mix(iStartColor, iEndColor, vUv.x);
  gl_FragColor = vec4(color, 1.0);
}

Audio-Reactive Pulse

void main() {
  float dist = length(vUv - 0.5);
  float pulse = iLowFreq * iIntensity;
  float c = smoothstep(0.3 + pulse * 0.2, 0.28 + pulse * 0.2, dist);
  gl_FragColor = vec4(mix(iEndColor, iStartColor, c), 1.0);
}

Beat-Synced Animation

void main() {
  float beat = sin(iGlobalTime * iBpm / 60.0 * TAU) * 0.5 + 0.5;
  vec3 color = mix(iStartColor, iEndColor, beat);
  color *= 1.0 + iLowFreq * iIntensity * 0.5;
  gl_FragColor = vec4(color, 1.0);
}

Frequency Bars

void main() {
  float barWidth = 0.05;
  float barIndex = floor(vUv.x / barWidth);
  float freq = getFrequency(barIndex / 20.0);
  float barHeight = freq * iIntensity * 0.5;
  float bar = step(1.0 - vUv.y, barHeight);
  vec3 color = mix(iStartColor, iEndColor, vUv.x);
  gl_FragColor = vec4(color * bar, 1.0);
}

Plasma Effect

void main() {
  float t = iGlobalTime * 0.5;
  float v = sin(vUv.x * 10.0 + t);
  v += sin((vUv.y * 10.0 + t) * 0.5);
  v += sin((vUv.x * 10.0 + vUv.y * 10.0 + t) * 0.5);
  v = v * 0.5 + 0.5;
  v += iLowFreq * iIntensity * 0.2;
  gl_FragColor = vec4(mix(iStartColor, iEndColor, v), 1.0);
}

Tips

Performance
  • Keep your shader code efficient. Avoid expensive operations in loops
  • Use built-in GLSL functions like mix, smoothstep, clamp
  • Test with different audio to ensure your visuals respond well
Audio Reactivity
  • iLowFreq responds to bass - great for pulses and beats
  • iMidFreq responds to vocals and instruments
  • iHighFreq responds to hi-hats and cymbals
  • Multiply audio values by iIntensity to make reactivity adjustable

Common Issues

Shader won't compile

Check the error message below the editor - it shows the line number where the error occurred. Common issues:

  • Missing semicolons
  • Undeclared variables
  • Type mismatches (e.g., using float where vec3 is expected)

Output is black

Make sure you're setting fragColor to a valid RGB value. Try starting with a simple gradient to verify your setup works.

Audio not reacting

Verify that you're using the audio uniforms (iLowFreq, iMidFreq, iHighFreq) in your calculations and that iIntensity is set above 0 in the UI.