// Author: Florian Morel
// Title: glsl-barrel-pincushion example
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
float rectangle(vec2 st, vec2 size, vec2 aastep) {
size = vec2(0.5) - size * 0.5;
vec2 uv = vec2(smoothstep(size.x - aastep.x, size.x, st.x), smoothstep(size.y - aastep.y, size.y, st.y));
uv *= vec2(smoothstep(size.x - aastep.x, size.x, 1.0 - st.x), smoothstep(size.y - aastep.y, size.y, 1.0 - st.y));
return uv.x * uv.y;
}
float lines(vec2 pos, vec2 axis, float gridSize, vec2 aastep) {
float lineWidth = 1.0;
vec2 gridPos = pos / gridSize;
vec2 gridFrac = abs(fract(gridPos) - 0.5);
vec2 g = clamp((gridFrac - aastep * (lineWidth - 1.0)) / aastep, 0.0, 1.0);
float c = g.x * g.y;
return 1.0 - c;
}
vec2 barrelPincushion(vec2 uv, float k) {
vec2 st = uv - 0.5;
float theta = atan(st.x, st.y);
float radius = sqrt(dot(st, st));
radius *= 1.0 + k * pow(radius, 2.0);
// return 0.5 + vec2(sin(theta), cos(theta)) * radius;
return vec2(
0.5 + sin(theta) * radius,
uv.y
);
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec2 aastep = 2.0 / u_resolution;
float k = sin(u_time);
st = barrelPincushion(st, k);
float shape = rectangle(st, vec2(0.5), aastep);
shape -= rectangle(st, vec2(0.49), aastep);
vec3 color = vec3(1.0);
float mask = rectangle(st, vec2(0.5), aastep);
color += -mask * lines(st, vec2(0.0), 0.05, aastep * 10.0);
gl_FragColor = vec4(color, 1.0 - shape);
}
The magic is in the barrelPincushion
function, the rest is basically for generating and drawing the rectangle. Previously it was taking an input co-ord, transforming it and returning the result. I modified the output to return the new co-ordinate for the X position, and the old for the Y.