shader/ellipsis_frag.glsl

changeset 173
bd57fe3f6360
parent 159
da7ebfcdd159
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shader/ellipsis_frag.glsl	Tue Jul 01 20:28:49 2025 +0200
@@ -0,0 +1,60 @@
+
+layout(location = 0) out vec4 diffuse;
+in vec2 uvcoord;
+
+uniform vec2 radii;
+#ifdef FILL
+uniform vec4 color;
+#endif
+#ifdef BORDER
+uniform float thickness;
+uniform vec4 border_color;
+#endif
+
+void main(void) {
+    // Calculate center of the ellipse
+    vec2 center = radii;
+
+    // Calculate position relative to center
+    vec2 pos = uvcoord - center;
+
+    // For an ellipse, we need to calculate normalized distance based on the formula:
+    // (x/a)² + (y/b)² = 1 where a and b are the semi-axes
+    vec2 normalized = pos / center;
+
+    // Calculate squared distance in ellipse space
+    // Value = 1.0 exactly at the ellipse boundary
+    float dist_squared = dot(normalized, normalized);
+
+    #ifndef BORDER
+    // For filled ellipse
+    if (dist_squared > 1.0) {
+        discard; // Outside the ellipse
+    }
+    diffuse = color;
+    #else // BORDER
+    // For outlined ellipse
+    // Calculate inner border threshold based on thickness
+    // We need to determine the inner ellipse boundary
+    float border_ratio = thickness / min(center.x, center.y);
+
+    // The inner ellipse has a smaller radius but follows the same equation
+    // We need to calculate what normalized value corresponds to the inner ellipse
+    float inner_threshold = 1.0 - border_ratio;
+    inner_threshold = inner_threshold * inner_threshold; // Square it because we're comparing to dist_squared
+
+    if (dist_squared > 1.0) {
+        discard; // Outside the ellipse
+    } else if (dist_squared > inner_threshold) {
+        // In the border region
+        diffuse = border_color;
+    } else {
+        // Inside the outline
+        #ifdef FILL
+        diffuse = color;
+        #else
+        discard;
+        #endif
+    }
+    #endif // BORDER
+}
\ No newline at end of file

mercurial