#version 130 in vec2 frag_uv; in vec2 original_coordinates; in vec4 clip_coordinates; uniform sampler2D base_texture; uniform int mode; /* [-1, 1] normalized device coordinates to [0, 1] UV coordinates */ vec2 ndc_to_uv(vec2 coordinates) { return (coordinates + 1) / 2; } /* coordinates in circle with radius <= 1 to box coordinates in [-1, 1] */ vec2 circle_to_box(vec2 circle) { float u = circle.x; float v = circle.y; float u_sq = pow(u, 2); float v_sq = pow(v, 2); float rt_2 = sqrt(2); float x = .5 * sqrt(2 + 2 * u * rt_2 + u_sq - v_sq) - .5 * sqrt(2 - 2 * u * rt_2 + u_sq - v_sq); float y = .5 * sqrt(2 + 2 * v * rt_2 - u_sq + v_sq) - .5 * sqrt(2 - 2 * v * rt_2 - u_sq + v_sq); return vec2(x, y); } /* box coordinates in [-1, 1] to coordinates in circle with radius <= 1 */ vec2 box_to_circle(vec2 box) { float u = box.x * sqrt(1 - .5 * pow(box.y, 2)); float v = box.y * sqrt(1 - .5 * pow(box.x, 2)); return vec2(u, v); } void main() { /* normalized device coordinates (coordinates in [-1, 1] space within viewport) */ vec2 ndc = original_coordinates; /* map to circle if requested */ if (mode == 1) { ndc = circle_to_box(ndc); } else if (mode == 2) { ndc = box_to_circle(ndc); } /* translate ndc to uv space and get texel */ gl_FragColor = texture(base_texture, ndc_to_uv(ndc)); }