Circle progress mirror

A mirrored circle progress bar

Shader code
shader_type canvas_item;

const float PI = 3.141592;
const float TAU = 6.283185;

uniform float outer_radius :hint_range(0., 1.) = 1.0;
uniform float inner_radius :hint_range(0., 1.) = 0.75;
uniform float turn :hint_range(0., 1.) = 0.0;
uniform float blur :hint_range(0., 1., .0001) = 0.005;
uniform float fill_ratio :hint_range(0., 1.) = 0.75;

float remap(float i_min, float i_max, float o_min, float o_max, float val) {
	float t = (val - i_min) / (i_max - i_min);
	return o_min + (o_max - o_min) * t;
}

vec2 rotate_uv(vec2 uv, vec2 pivot, float rotation) {
    float cosa = cos(rotation);
    float sina = sin(rotation);
    uv -= pivot;
    return vec2(
        cosa * uv.x - sina * uv.y,
        cosa * uv.y + sina * uv.x 
    ) + pivot;
}

float circle(vec2 uv, float value)
{   
	float d = length(uv);
	float t = smoothstep(
		inner_radius + blur,
		inner_radius - blur,
		d
	) - smoothstep(
		outer_radius + blur,
		outer_radius - blur,
		d
	);   

	return t;
}

float mask(vec2 uv, float value)
{
	float r = atan(uv.x, uv.y);
	r = remap(-PI, PI, 0.0, 1.0, r);
	r = step(r, value * 0.5);
	
	uv.x = uv.x + 1.0;
	uv.x = uv.x * -1.0;
	uv.x += 1.0;
	float l = atan(uv.x, uv.y);
	l = remap(-PI, PI, 0.0, 1.0, l);
	l = step(l, value * 0.5);
	
	return r + l ;
}

void fragment() {
	vec2 uv = (UV * 2.0) - 1.0;
	vec2 origin = vec2(0.0, 0.0);
	uv = rotate_uv(uv, origin, turn * TAU);
	float t = mask(uv, fill_ratio);
	float c = circle(uv, 0.5);
	COLOR = vec4(t * c);
}
Tags
circle, progress, SDF
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from afk

Joepli wobble

Tilemap Wind shader

Tilemap cell UV

Related shaders

2D mirror effect

another wave Progress Shader

Radial Progress Shader

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
LadyPhenom
5 months ago

Excellent shader! If anyone needs this to be unmirrored (for a radial progress bar, for example), you can change line 62 to be:

uv = rotate_uv(uv, origin, (turn - fill_ratio/2.0) * TAU);