Skip to main content

GLSL Shader Playground

Write a GLSL fragment shader and watch it draw in your browser, with compiler messages on your own lines, mouse input and a PNG export.

// Shadertoy style: write mainImage, the page calls it for every pixel.
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord / iResolution.xy;
vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0.0, 2.0, 4.0));
fragColor = vec4(col, 1.0);
}

PictureDrawing
60 fps
  • Compiler messages appear here.

Shortcuts: Ctrl+Enter run · / search (use ⌘ on Mac)

Free Online GLSL Shader Editor

Write a shader and watch it draw. Type a GLSL fragment shader on the left and the picture on the right updates as you type, with errors shown on your own lines. Drag the mouse over the picture to feed it your position, save a frame as a PNG, and download your files as one zip. Nothing you write is uploaded. Use it to learn how fragment shaders work, try an effect before putting it in a game or a page, or paste a single-pass Shadertoy shader and see it run.

How to use the shader editor

  1. Pick an example from Load an example… or edit image.frag. Write a function mainImage that sets fragColor for each pixel.
  2. Use iResolution for the picture size, iTime for seconds since the start, and iMouse for where you click and drag on the picture.
  3. Read the compiler messages under the picture. Each one names your file and line; click one to jump to it.
  4. Use Pause, Restart and Save PNG under the picture.
  5. Put shared functions in common.glsl and pull them in with #include "common.glsl".

Good to know

This editor runs one shader, in the style of Shadertoy's image pass: no textures, sound or extra buffers. It needs a browser and device that support WebGL2. If a shader is too slow for your device, the page pauses it and says so. For web page effects without shaders, try the CSS Effects Generator.

Worked example

The first example turns the position of every pixel into a colour that changes over time:

// Shadertoy style: write mainImage, the page calls it for every pixel.
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  vec2 uv = fragCoord / iResolution.xy;
  vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0.0, 2.0, 4.0));
  fragColor = vec4(col, 1.0);
}

Result: a smooth gradient that drifts through colours. If you remove the ; after vec2 uv = fragCoord / iResolution.xy, the message says what is wrong and on which line.

Common mistakes

  • Writing float x = 1; instead of 1.0: GLSL does not convert whole numbers to decimals for you.
  • Dividing by iResolution instead of iResolution.xy or iResolution.y.
  • Forgetting to set fragColor: the picture stays black.
  • Very long loops: a shader that runs too slowly makes the picture stutter and is paused.

Frequently asked questions

What is a fragment shader?
A small program that runs on your graphics card once for every pixel and decides that pixel's colour. Here the picture is made only by your shader, so a few lines of maths can draw gradients, patterns or whole 3D scenes.
How do I write one?
Write a function called mainImage that sets fragColor for the pixel at fragCoord. You can use iResolution (the picture size), iTime (seconds since start), iMouse (where you click and drag) and iFrame (the frame number). The examples menu has six to start from.
Can I paste a shader from Shadertoy?
Yes for most single-pass shaders: paste the code with mainImage and it runs. Shaders that need textures, sound or several buffers are not supported.
What if I write void main instead?
It works too. The page adds the uniforms u_resolution, u_time and u_mouse and an output called fragColor if you do not declare them. If your code starts with its own #version line it is used exactly as you wrote it.
Why do the error lines match my code?
The page adds a few lines above your code before compiling. It subtracts them again, so each message points at the line in your own file.
Is my shader uploaded?
No. The shader is compiled and drawn by your own graphics card in your browser. Nothing is sent anywhere.
Is this a replacement for Shadertoy?
For single-pass shaders, yes: write mainImage and use iTime, iResolution and iMouse. It has no textures, sound or multi-pass buffers, and nothing is uploaded or published.

Related tools

More Playground

View all Playground tools →