You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.5 KiB
GLSL
76 lines
2.5 KiB
GLSL
#ifdef GL_ES
|
|
precision mediump float;
|
|
#endif
|
|
|
|
const float TWOPI = 6.28318548;
|
|
const float PI = 3.14159274;
|
|
const float RING_FUDGE_FACTOR = 0.05;
|
|
|
|
const float GLOW_OVERSHOOT = 0.3;
|
|
|
|
uniform vec2 m_CenterPos;
|
|
uniform float m_OuterRadius;
|
|
uniform float m_InnerRadius;
|
|
uniform float m_OuterGlowRadius;
|
|
uniform float m_InnerGlowRadius;
|
|
|
|
uniform float m_Alpha;
|
|
|
|
uniform vec4 m_RingForegroundColour;
|
|
uniform vec4 m_RingBackgroundColour;
|
|
uniform vec4 m_GlowColour; // Normalized
|
|
|
|
uniform float m_Progress;
|
|
|
|
varying vec2 v_Position;
|
|
|
|
/**
|
|
* Returns 1.0 if m_InnerRadius < dist < m_OuterRadius.
|
|
*/
|
|
float isRing(float dist)
|
|
{
|
|
return smoothstep(m_InnerRadius, m_InnerRadius + 1.0, dist)
|
|
* smoothstep(m_OuterRadius, m_OuterRadius - 1.0, dist);
|
|
}
|
|
|
|
/**
|
|
* If m_InnerGlowRadius < dist < m_InnerRadius || m_OuterRadius < dist < m_OuterGlowRadius
|
|
* returns the linear interpolation of the glow bewteen those bounds.
|
|
* Returns 0 if no glow.
|
|
*/
|
|
float isGlow(float dist)
|
|
{
|
|
return smoothstep(m_InnerGlowRadius, m_InnerRadius, dist) // Before the ring
|
|
* clamp(1.0 - isRing(dist), 0.0, 1.0) // During the ring
|
|
* smoothstep(m_OuterGlowRadius, m_OuterRadius, dist); // After the ring
|
|
}
|
|
|
|
void main(void)
|
|
{
|
|
// Radius from the center
|
|
float dist = distance(v_Position, m_CenterPos);
|
|
|
|
// Top of area is at -PI / PI, bottom is 0
|
|
float angle = atan(v_Position.x - m_CenterPos.x, v_Position.y - m_CenterPos.y);
|
|
float startAngle = (0.5 - m_Progress) * TWOPI;
|
|
|
|
// Glow and AA reduction once the ring is too small
|
|
float reduction = smoothstep(PI, PI - GLOW_OVERSHOOT, startAngle);
|
|
|
|
float activeRingAmount = smoothstep(startAngle - reduction * RING_FUDGE_FACTOR, startAngle, angle);
|
|
|
|
float activeGlowAmount = max(smoothstep(startAngle - GLOW_OVERSHOOT, startAngle + GLOW_OVERSHOOT, angle), // Start
|
|
smoothstep(-PI + GLOW_OVERSHOOT, -PI - GLOW_OVERSHOOT, angle)) // Top (left)
|
|
* reduction * smoothstep(PI + GLOW_OVERSHOOT / 2.0, PI - GLOW_OVERSHOOT / 2.0, angle); // Top (right)
|
|
|
|
activeGlowAmount += max(0.0, (1.0 - activeGlowAmount) * smoothstep(0.9, 1.0, m_Progress));
|
|
|
|
// Todo: Probably make darkening uniforms
|
|
vec4 glowColour = isGlow(dist) * (activeGlowAmount + (1.0 - activeGlowAmount) * 0.2) * m_GlowColour;
|
|
vec4 ringColour = isRing(dist) * (activeRingAmount * m_RingForegroundColour + (1.0 - activeRingAmount) * m_RingBackgroundColour);
|
|
|
|
gl_FragColor = (ringColour + glowColour) * m_Alpha;
|
|
|
|
//Todo: Discard fragments? idk...
|
|
}
|