spacebox/demo/squircle/flat.frag

52 lines
1.4 KiB
GLSL

#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));
}