summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl
diff options
context:
space:
mode:
authorNippy <nippy@Nippy-Mac-mini.local>2026-10-09 17:23:53 +0200
committerNippy <nippy@Nippy-Mac-mini.local>2026-10-09 17:23:53 +0200
commit9d5be1660d8f74038ebed3d74fdbc809e43787ae (patch)
tree4cb46c3765be87ca4c5219f2f714425d7dfddb56 /raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl
parentdeb4b8a9c407832c35100a643bd7a592589c9679 (diff)
downloadRaveOS-PKGBUILD-9d5be1660d8f74038ebed3d74fdbc809e43787ae.tar.gz
RaveOS-PKGBUILD-9d5be1660d8f74038ebed3d74fdbc809e43787ae.zip
gnome fix
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl')
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl412
1 files changed, 412 insertions, 0 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl
new file mode 100644
index 0000000..5d1d241
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl
@@ -0,0 +1,412 @@
+// GLSL port of winaviation-tweaks/liquidass LiquidAssBackboardd/Tweak.mm kShaderSrc.
+// The sampling and blur pass are adapted for Blur my Shell's Clutter pipeline.
+uniform sampler2D tex;
+uniform float width;
+uniform float height;
+uniform float strength;
+uniform float blur_radius;
+uniform float edge_size;
+uniform float falloff;
+uniform float corner_radius;
+uniform float rim_width;
+uniform float rgb_fringing;
+uniform float gloss;
+uniform float tint;
+uniform float tint_r;
+uniform float tint_g;
+uniform float tint_b;
+uniform float tint_a;
+uniform float backdrop_zoom;
+uniform float shadow;
+uniform int texture_repeat;
+uniform int blur_direction;
+uniform int private_pass;
+uniform float clip_x0;
+uniform float clip_y0;
+uniform float clip_width;
+uniform float clip_height;
+uniform float opacity_factor;
+
+const float PI = 3.14159265;
+const float REFRACTIVE_INDEX = 1.52;
+const float DISPERSION_SCALE = 20.0;
+
+const float kDispersionRedIndex = 0.98;
+const float kDispersionGreenIndex = 1.00;
+const float kDispersionBlueIndex = 1.02;
+
+float surfaceConvexSquircle(float x) {
+ return pow(1.0 - pow(1.0 - x, 4.0), 0.25);
+}
+
+vec2 refractRay(vec2 normal, float eta) {
+ float cosI = -normal.y;
+ float k = 1.0 - eta * eta * (1.0 - cosI * cosI);
+ if (k < 0.0)
+ return vec2(0.0);
+
+ float kSqrt = sqrt(k);
+ return vec2(
+ -(eta * cosI + kSqrt) * normal.x,
+ eta - (eta * cosI + kSqrt) * normal.y
+ );
+}
+
+float rawRefraction(float bezelRatio, float glassThickness, float bezelWidth, float eta) {
+ float x = clamp(bezelRatio, 0.05, 0.95);
+ float y = surfaceConvexSquircle(x);
+ float y2 = surfaceConvexSquircle(x + 0.001);
+ float deriv = (y2 - y) / 0.001;
+ float mag = sqrt(deriv * deriv + 1.0);
+ vec2 n = vec2(-deriv / mag, -1.0 / mag);
+ vec2 r = refractRay(n, eta);
+ if (length(r) < 0.0001 || abs(r.y) < 0.0001)
+ return 0.0;
+
+ float remaining = y * bezelWidth + glassThickness;
+ return r.x * (remaining / r.y);
+}
+
+float displacementAtRatio(float bezelRatio, float glassThickness, float bezelWidth, float eta) {
+ float peak = rawRefraction(0.05, glassThickness, bezelWidth, eta);
+ if (abs(peak) < 0.0001)
+ return 0.0;
+
+ float raw = rawRefraction(bezelRatio, glassThickness, bezelWidth, eta);
+ float norm = raw / peak;
+ float profileFalloff = 1.0 - smoothstep(0.0, 1.0, bezelRatio);
+ return norm * profileFalloff;
+}
+
+float fresnelAtRatio(float bezelRatio, float refractiveIndex) {
+ float x = clamp(bezelRatio, 0.02, 0.98);
+ float y0 = surfaceConvexSquircle(max(0.001, x - 0.001));
+ float y1 = surfaceConvexSquircle(min(0.999, x + 0.001));
+ float slope = (y1 - y0) / 0.002;
+ float cosTheta = inversesqrt(1.0 + slope * slope);
+ float f0Base = (refractiveIndex - 1.0) / (refractiveIndex + 1.0);
+ float f0 = f0Base * f0Base;
+ float grazing = pow(1.0 - clamp(cosTheta, 0.0, 1.0), 5.0);
+ float fresnel = f0 + (1.0 - f0) * grazing;
+ return fresnel * (1.0 - smoothstep(0.0, 1.0, bezelRatio));
+}
+
+float dispersionOffsetScale(float channelIndex, float strengthValue) {
+ return 1.0 - (channelIndex - 1.0) * strengthValue;
+}
+
+float luminance(vec3 color) {
+ return dot(color, vec3(0.2126, 0.7152, 0.0722));
+}
+
+vec2 clampUV(vec2 uv) {
+ vec2 px = vec2(1.5 / width, 1.5 / height);
+ return clamp(uv, px, vec2(1.0) - px);
+}
+
+vec2 resolveUV(vec2 uv) {
+ if (texture_repeat == 1) {
+ vec2 mirrored = abs(fract(uv * 0.5) * 2.0 - 1.0);
+ return clampUV(mirrored);
+ }
+
+ return clampUV(uv);
+}
+
+vec4 sampleBackdrop(vec2 uv) {
+ return texture2D(tex, resolveUV(uv));
+}
+
+vec4 sampleGlassBackdrop(vec2 uv) {
+ if (blur_radius <= 0.01)
+ return sampleBackdrop(uv);
+
+ float sigma = max(0.1, blur_radius * 0.5);
+ float pixelStep = blur_direction == 1 ? 1.0 / width : 1.0 / height;
+ vec2 direction = vec2(float(blur_direction), 1.0 - float(blur_direction));
+
+ vec3 gauss;
+ gauss.x = 1.0 / (sqrt(2.0 * PI) * sigma);
+ gauss.y = exp(-0.5 / (sigma * sigma));
+ gauss.z = gauss.y * gauss.y;
+
+ vec4 accum = sampleBackdrop(uv) * gauss.x;
+ float weightSum = gauss.x;
+
+ gauss.xy *= gauss.yz;
+
+ int radius = int(ceil(1.5 * sigma)) * 2;
+ for (int i = 1; i <= radius; i += 2) {
+ float subtotal = gauss.x;
+
+ gauss.xy *= gauss.yz;
+ subtotal += gauss.x;
+
+ float gaussRatio = gauss.x / subtotal;
+ float offset = float(i) + gaussRatio;
+ vec2 uvOffset = direction * offset * pixelStep;
+
+ accum += sampleBackdrop(uv + uvOffset) * subtotal;
+ accum += sampleBackdrop(uv - uvOffset) * subtotal;
+ weightSum += subtotal * 2.0;
+
+ gauss.xy *= gauss.yz;
+ }
+
+ return accum / weightSum;
+}
+
+vec4 tintFallbackSample() {
+ return vec4(vec3(tint_r, tint_g, tint_b), 1.0);
+}
+
+vec4 sampleOrTintFallback(vec2 uv) {
+ vec4 sample = sampleGlassBackdrop(uv);
+ return sample.a < 0.01 ? tintFallbackSample() : sample;
+}
+
+float roundedBoxDistance(vec2 p, vec2 halfSize, float radius) {
+ radius = min(radius, min(halfSize.x, halfSize.y));
+ vec2 q = abs(p) - halfSize + vec2(radius);
+ return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
+}
+
+float squircleCornerDistance(vec2 p, vec2 halfSize, float radius) {
+ const float continuousCornerExtent = 1.528;
+
+ vec2 extent = min(vec2(radius * continuousCornerExtent), halfSize);
+ vec2 core = max(halfSize - extent, vec2(0.0));
+ vec2 q = abs(p) - core;
+ vec2 corner = max(q, vec2(0.0));
+ vec2 normalized = corner / max(extent, vec2(0.001));
+ float superLength = pow(pow(normalized.x, 4.0) + pow(normalized.y, 4.0), 0.25);
+
+ if (q.x <= 0.0 && q.y <= 0.0)
+ return -min(halfSize.x - abs(p.x), halfSize.y - abs(p.y));
+
+ return (superLength - 1.0) * min(extent.x, extent.y);
+}
+
+struct EdgeInfo {
+ float distance;
+ float alpha;
+ vec2 dir;
+};
+
+EdgeInfo estimateAnalyticEdge(vec2 px, vec2 halfSize, float radius, float shortest) {
+ vec2 p = px - halfSize;
+ float signedDistance;
+ vec2 core;
+
+ if (radius >= shortest * 0.49 || radius < 0.5) {
+ core = max(halfSize - vec2(radius), vec2(0.0));
+ signedDistance = roundedBoxDistance(p, halfSize, radius);
+ } else {
+ const float continuousCornerExtent = 1.528;
+ vec2 extent = min(vec2(radius * continuousCornerExtent), halfSize);
+ core = max(halfSize - extent, vec2(0.0));
+ signedDistance = squircleCornerDistance(p, halfSize, radius);
+ }
+
+ EdgeInfo info;
+ info.distance = max(0.0, -signedDistance);
+ info.alpha = clamp(1.0 - max(0.0, signedDistance), 0.0, 1.0);
+
+ vec2 cornerDelta = max(abs(p) - core, vec2(0.0));
+ vec2 normalDelta;
+
+ if (radius < shortest * 0.49 && radius >= 0.5 &&
+ cornerDelta.x > 0.0 && cornerDelta.y > 0.0) {
+ normalDelta = sign(p) * pow(cornerDelta, vec2(3.0));
+ } else {
+ vec2 nearestCore = clamp(p, -core, core);
+ normalDelta = p - nearestCore;
+ }
+
+ float normalLength = length(normalDelta);
+
+ if (normalLength > 0.001) {
+ info.dir = normalDelta / normalLength;
+ } else {
+ vec2 lensPx = px;
+ float dL = lensPx.x;
+ float dR = halfSize.x * 2.0 - lensPx.x;
+ float dT = lensPx.y;
+ float dB = halfSize.y * 2.0 - lensPx.y;
+ float dm = min(min(dL, dR), min(dT, dB));
+
+ info.dir = vec2(
+ (dL < dR && dL == dm) ? -1.0 : (dR <= dL && dR == dm) ? 1.0 : 0.0,
+ (dT < dB && dT == dm) ? -1.0 : (dB <= dT && dB == dm) ? 1.0 : 0.0
+ );
+ }
+
+ return info;
+}
+
+vec2 backdropSampleUV(vec2 sampleUV, vec2 displacementPx) {
+ vec2 displaced = sampleUV + displacementPx / vec2(width, height);
+ float zoom = max(backdrop_zoom, 0.01);
+
+ displaced = vec2(0.5) + (displaced - vec2(0.5)) / zoom;
+ return displaced;
+}
+
+vec4 sampleDispersed(vec2 sampleUV, vec2 dispPx, float dispersion) {
+ float greenScale = dispersionOffsetScale(kDispersionGreenIndex, dispersion);
+ vec2 greenUV = resolveUV(backdropSampleUV(sampleUV, dispPx * greenScale));
+ vec4 greenSample = sampleGlassBackdrop(greenUV);
+
+ vec4 fallback = vec4(0.0);
+ bool loadedFallback = false;
+ if (greenSample.a < 0.01) {
+ vec2 fallbackUV = resolveUV(backdropSampleUV(sampleUV, vec2(0.0)));
+
+ fallback = sampleOrTintFallback(fallbackUV);
+ loadedFallback = true;
+ greenSample = fallback;
+ }
+
+ if (greenSample.a < 0.01)
+ return tintFallbackSample();
+
+ vec4 bg = greenSample;
+ if (dispersion > 0.001 && dot(dispPx, dispPx) > 0.0001) {
+ float redScale = dispersionOffsetScale(kDispersionRedIndex, dispersion);
+ float blueScale = dispersionOffsetScale(kDispersionBlueIndex, dispersion);
+
+ vec2 redUV = resolveUV(backdropSampleUV(sampleUV, dispPx * redScale));
+ vec2 blueUV = resolveUV(backdropSampleUV(sampleUV, dispPx * blueScale));
+ vec4 redSample = sampleGlassBackdrop(redUV);
+ vec4 blueSample = sampleGlassBackdrop(blueUV);
+
+ if (redSample.a < 0.01 || blueSample.a < 0.01) {
+ if (!loadedFallback) {
+ vec2 fallbackUV = resolveUV(backdropSampleUV(sampleUV, vec2(0.0)));
+ fallback = sampleOrTintFallback(fallbackUV);
+ }
+
+ if (redSample.a < 0.01)
+ redSample = fallback.a < 0.01 ? tintFallbackSample() : fallback;
+
+ if (blueSample.a < 0.01)
+ blueSample = fallback.a < 0.01 ? tintFallbackSample() : fallback;
+ }
+
+ bg.r = redSample.r;
+ bg.g = greenSample.g;
+ bg.b = blueSample.b;
+ bg.a = greenSample.a;
+ }
+ return bg;
+}
+
+vec4 applyTintAndShadow(vec4 sample, vec2 localUV, float alpha) {
+ vec3 tintColor = vec3(tint_r, tint_g, tint_b);
+ vec3 outRGB = mix(sample.rgb, tintColor, tint * tint_a);
+
+ outRGB *= 1.0 - smoothstep(0.25, 1.0, localUV.y) * shadow * 0.20;
+
+ return vec4(clamp(outRGB, 0.0, 1.0) * alpha, alpha);
+}
+
+void main() {
+ vec2 actorSize = vec2(width, height);
+ vec2 actorUV = cogl_tex_coord_in[0].xy;
+
+ if (private_pass == 1) {
+ cogl_color_out = sampleGlassBackdrop(actorUV);
+ return;
+ }
+
+ vec2 actorPx = actorUV * actorSize;
+ vec4 bounds = clip_width < 0.0 || clip_height < 0.0
+ ? vec4(0.0, 0.0, width, height)
+ : vec4(clip_x0, clip_y0, clip_x0 + clip_width, clip_y0 + clip_height);
+
+ vec2 glassSize = max(bounds.zw - bounds.xy, vec2(1.0));
+ vec2 glassPx = actorPx - bounds.xy;
+ vec2 halfSize = glassSize * 0.5;
+ vec2 localUV = glassPx / glassSize;
+
+ float W = glassSize.x;
+ float H = glassSize.y;
+ float shortestSide = min(W, H);
+ float R = clamp(corner_radius, 0.0, shortestSide * 0.5);
+ float bezel = max(1.0, min(edge_size, shortestSide * 0.5));
+ float glassThickness = max(0.5, edge_size * 0.55 * falloff);
+ float eta = 1.0 / REFRACTIVE_INDEX;
+
+ bool nearlySquare = abs(W - H) < max(4.0, shortestSide * 0.035);
+ bool useCircularSurface = nearlySquare && R >= shortestSide * 0.34;
+
+ EdgeInfo edge = estimateAnalyticEdge(glassPx, halfSize, R, shortestSide);
+ if (edge.alpha <= 0.0) {
+ cogl_color_out = vec4(0.0);
+ return;
+ }
+
+ float distFromSide = edge.distance;
+ float edgeOpacity = edge.alpha;
+ float edgeBand = 1.0;
+ float refractionBand = bezel;
+ vec2 dir = edge.dir;
+
+ if (useCircularSurface) {
+ float circleRadius = shortestSide * 0.5;
+ vec2 circleCenter = glassSize * 0.5;
+ vec2 fromCenter = glassPx - circleCenter;
+ float circleDistance = length(fromCenter);
+
+ if (circleDistance > circleRadius + 1.0) {
+ cogl_color_out = vec4(0.0);
+ return;
+ }
+
+ distFromSide = max(0.0, circleRadius - circleDistance);
+ dir = circleDistance > 0.001 ? normalize(fromCenter) : vec2(0.0, -1.0);
+ edgeOpacity = clamp(1.0 - max(0.0, circleDistance - circleRadius), 0.0, 1.0);
+
+ float rimRadius = max(1.0, bezel * 0.35);
+ refractionBand = rimRadius;
+ edgeBand = clamp(1.0 - (distFromSide / rimRadius), 0.0, 1.0);
+ } else {
+ float rimRadius = max(1.0, bezel * 0.35 * max(1.0, rim_width));
+ refractionBand = rimRadius;
+ edgeBand = clamp(1.0 - (distFromSide / rimRadius), 0.0, 1.0);
+ }
+
+ if (!useCircularSurface && R < shortestSide * 0.45 && distFromSide >= refractionBand) {
+ vec2 flatUV = backdropSampleUV(actorUV, vec2(0.0));
+ vec4 flatSample = sampleOrTintFallback(resolveUV(flatUV));
+ float finalOpacity = edgeOpacity * opacity_factor;
+
+ cogl_color_out = applyTintAndShadow(flatSample, localUV, finalOpacity);
+ return;
+ }
+
+ float bezelRatio = clamp(distFromSide / refractionBand, 0.0, 1.0);
+ float normDisp = distFromSide < refractionBand
+ ? displacementAtRatio(bezelRatio, glassThickness, refractionBand, eta)
+ : 0.0;
+ float dispStrength = useCircularSurface ? edgeOpacity : edgeBand;
+ vec2 dispPx = -dir * normDisp * refractionBand * strength * dispStrength;
+
+ float dispersion = clamp(rgb_fringing * DISPERSION_SCALE, 0.0, 20.0);
+ vec4 bgColor = sampleDispersed(actorUV, dispPx, dispersion);
+ if (bgColor.a < 0.01) {
+ cogl_color_out = vec4(0.0);
+ return;
+ }
+
+ vec3 outRGB = mix(bgColor.rgb, vec3(tint_r, tint_g, tint_b), tint * tint_a);
+ float fresnel = fresnelAtRatio(bezelRatio, REFRACTIVE_INDEX) * edgeOpacity;
+ float bgLuminance = luminance(outRGB);
+ float glare = clamp(fresnel * 0.70 * mix(0.40, 1.0, bgLuminance), 0.0, 0.18)
+ * clamp(gloss, 0.0, 1.0);
+ outRGB = 1.0 - (1.0 - outRGB) * (1.0 - glare);
+ outRGB *= 1.0 - smoothstep(0.25, 1.0, localUV.y) * shadow * 0.20;
+
+ float finalOpacity = edgeOpacity * opacity_factor;
+ cogl_color_out = vec4(clamp(outRGB, 0.0, 1.0) * finalOpacity, finalOpacity);
+}