@shaders
A GLSL fragment shader rendered with WebGL, as a background image or as a live
<canvas> with @content.
Syntax
- @shaders(<fragment source>)
- @shaders(fragment { ... } texture0 { <doodle code> })
- @shaders<width>x<height>(...)
The body is either fragment shader source, or named sections: fragment { }, vertex { }
and any number of texture… sections. A texture section holds a doodle which is rendered to an image
and bound as a sampler2D of that name. The size suffix caps the raster size.
| Uniform | Value |
|---|---|
vec2 u_resolution | canvas size in pixels |
float u_time | seconds since the shader started |
float u_timeDelta | seconds since the previous frame |
int u_frameIndex | frame counter |
vec2 u_mouse | pointer position over the doodle, in pixels |
vec2 u_seed | two values derived from the seed and the cell |
Write the output to FragColor or to gl_FragColor, both are accepted, and
texture2D() is mapped to texture(). A Shadertoy-style mainImage() with
iResolution, iTime, iMouse and iChannel0 works as is.
A shader that reads u_time, u_timeDelta or u_frameIndex is redrawn every frame.
// comments are allowed inside the body.
Examples
@grid: 1 / 60vmin;
background: @shaders(
void main() {
vec2 p = gl_FragCoord.xy / u_resolution.xy;
FragColor = vec4(p.yx, .8, 1.);
}
); Animated, as a canvas:
@grid: 1 / 60vmin;
@content: @shaders(
void main() {
vec2 uv = (gl_FragCoord.xy / u_resolution - .5) * 2.;
float a = atan(uv.y, uv.x);
float r = length(uv);
vec3 c = vec3(1., 2., 3.);
c = .4 + .6 * cos(c + a*2. + r*6. - u_time);
FragColor = vec4(c, 1.0);
}
); A doodle as a texture:
@grid: 1 / 60vmin;
@content: @shaders(
fragment {
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution;
uv.x += sin(uv.y * 20. + u_time) * .02;
FragColor = texture(texture0, uv);
}
}
texture0 {
@grid: 8 / 100%;
background: @p(#000, #e6437d, #ebbf4d);
}
);