From 95bde46e395dbdcd56589e1da6b92c9bfdb98936 Mon Sep 17 00:00:00 2001 From: Justin Garza Date: Sat, 4 Jan 2025 19:06:05 -0500 Subject: [PATCH] 20250104 --- metadata.json | 2 +- resources/shaders/aura-glow.frag | 48 -- resources/shaders/common.glsl | 49 ++ resources/shaders/simple-fade.frag | 465 +++++++++++++++++- ...nsions.burn-my-windows-profile.gschema.xml | 6 + src/effects/SimpleFade.js | 13 +- 6 files changed, 506 insertions(+), 77 deletions(-) diff --git a/metadata.json b/metadata.json index 9053a09..a8cd7b5 100644 --- a/metadata.json +++ b/metadata.json @@ -15,5 +15,5 @@ "47" ], "url": "https://github.com/Schneegans/Burn-My-Windows", - "version": 45 + "version": 47 } \ No newline at end of file diff --git a/resources/shaders/aura-glow.frag b/resources/shaders/aura-glow.frag index c08ea69..ad4d45d 100644 --- a/resources/shaders/aura-glow.frag +++ b/resources/shaders/aura-glow.frag @@ -58,54 +58,6 @@ uniform float uEdgeSize; uniform float uEdgeHardness; - -vec3 offsetHue(vec3 color, float hueOffset) { - // Convert RGB to HSV - float maxC = max(max(color.r, color.g), color.b); - float minC = min(min(color.r, color.g), color.b); - float delta = maxC - minC; - - float hue = 0.0; - if (delta > 0.0) { - if (maxC == color.r) { - hue = mod((color.g - color.b) / delta, 6.0); - } else if (maxC == color.g) { - hue = (color.b - color.r) / delta + 2.0; - } else { - hue = (color.r - color.g) / delta + 4.0; - } - } - hue /= 6.0; - - float saturation = (maxC > 0.0) ? (delta / maxC) : 0.0; - float value = maxC; - - // Offset the hue - hue = mod(hue + hueOffset, 1.0); - - // Convert HSV back to RGB - float c = value * saturation; - float x = c * (1.0 - abs(mod(hue * 6.0, 2.0) - 1.0)); - float m = value - c; - - vec3 rgb; - if (hue < 1.0 / 6.0) { - rgb = vec3(c, x, 0.0); - } else if (hue < 2.0 / 6.0) { - rgb = vec3(x, c, 0.0); - } else if (hue < 3.0 / 6.0) { - rgb = vec3(0.0, c, x); - } else if (hue < 4.0 / 6.0) { - rgb = vec3(0.0, x, c); - } else if (hue < 5.0 / 6.0) { - rgb = vec3(x, 0.0, c); - } else { - rgb = vec3(c, 0.0, x); - } - - return rgb + m; -} - // A simple blur function vec4 blur(vec2 uv, float radius, float samples) { vec4 color = vec4(0.0); diff --git a/resources/shaders/common.glsl b/resources/shaders/common.glsl index fea52b3..0ed9395 100644 --- a/resources/shaders/common.glsl +++ b/resources/shaders/common.glsl @@ -185,6 +185,55 @@ vec3 darken(vec3 color, float fac) { return color * (1.0 - fac); } // color will be white. vec3 lighten(vec3 color, float fac) { return color + (vec3(1.0) - color) * fac; } + +//change the color based on an offset amount +vec3 offsetHue(vec3 color, float hueOffset) { + // Convert RGB to HSV + float maxC = max(max(color.r, color.g), color.b); + float minC = min(min(color.r, color.g), color.b); + float delta = maxC - minC; + + float hue = 0.0; + if (delta > 0.0) { + if (maxC == color.r) { + hue = mod((color.g - color.b) / delta, 6.0); + } else if (maxC == color.g) { + hue = (color.b - color.r) / delta + 2.0; + } else { + hue = (color.r - color.g) / delta + 4.0; + } + } + hue /= 6.0; + + float saturation = (maxC > 0.0) ? (delta / maxC) : 0.0; + float value = maxC; + + // Offset the hue + hue = mod(hue + hueOffset, 1.0); + + // Convert HSV back to RGB + float c = value * saturation; + float x = c * (1.0 - abs(mod(hue * 6.0, 2.0) - 1.0)); + float m = value - c; + + vec3 rgb; + if (hue < 1.0 / 6.0) { + rgb = vec3(c, x, 0.0); + } else if (hue < 2.0 / 6.0) { + rgb = vec3(x, c, 0.0); + } else if (hue < 3.0 / 6.0) { + rgb = vec3(0.0, c, x); + } else if (hue < 4.0 / 6.0) { + rgb = vec3(0.0, x, c); + } else if (hue < 5.0 / 6.0) { + rgb = vec3(x, 0.0, c); + } else { + rgb = vec3(c, 0.0, x); + } + + return rgb + m; +} + // ---------------------------------------------------------------------- easing functions // Here are some basic easing function. More can be added if required! diff --git a/resources/shaders/simple-fade.frag b/resources/shaders/simple-fade.frag index 39d09db..686bca7 100644 --- a/resources/shaders/simple-fade.frag +++ b/resources/shaders/simple-fade.frag @@ -33,16 +33,151 @@ // The width of the fading effect is loaded from the settings. // uniform float uFadeWidth; +float uSparkCount = 50.0; +vec2 uSparkStartEnd = vec2(0.1,0.75); +float uSparkOffset = 0.25; + float uBlurQuality = 5.0; -vec4 uSeed = vec4(0.4,0.2,0.4,0.6); +vec4 uSeed = vec4(1.0,0.1,0.5,1.0); + +float uStarCount = 5.0; +float uStarRot = 1.0; +float uStarSize = 0.1; +vec2 uStarStartEnd = vec2(0.0,0.66); + +//pastel +// vec4 uParticleColor0 = vec4(1.0, 0.8, 0.8, 1.0); +// vec4 uParticleColor1 = vec4(1.0, 1.0, 0.8, 1.0); +// vec4 uParticleColor2 = vec4(0.8, 1.0, 0.8, 1.0); +// vec4 uParticleColor3 = vec4(0.8, 0.8, 1.0, 1.0); +// vec4 uParticleColor4 = vec4(1.0, 0.8, 1.0, 1.0); +// vec4 uParticleColor5 = vec4(0.8, 1.0, 1.0, 1.0); + +//bold colors +vec4 uParticleColor0 = vec4(1.0, 0.0, 0.0, 0.0); +vec4 uParticleColor1 = vec4(1.0, 1.0, 0.0, 0.0); +vec4 uParticleColor2 = vec4(0.0, 1.0, 0.0, 0.0); +vec4 uParticleColor3 = vec4(0.0, 0.0, 1.0, 0.0); +vec4 uParticleColor4 = vec4(1.0, 0.0, 1.0, 0.0); +vec4 uParticleColor5 = vec4(0.0, 1.0, 1.0, 0.0); + + +vec4 uStarColor0 = vec4(1.0, 0.0, 0.0, 0.0); +vec4 uStarColor1 = vec4(1.0, 1.0, 0.0, 0.0); +vec4 uStarColor2 = vec4(0.0, 1.0, 0.0, 0.0); +vec4 uStarColor3 = vec4(0.0, 0.0, 1.0, 0.0); +vec4 uStarColor4 = vec4(1.0, 0.0, 1.0, 0.0); +vec4 uStarColor5 = vec4(1.0, 0.0, 0.0, 0.0); + + + + + +// Define a constant for 2 * PI (tau), which represents a full circle in radians. +const float PI = 3.14159265359; +const float tau = 6.28318530718; + +//helps to find the angle +vec3 getPosByAngle(float angle) +{ + return vec3(cos(angle), sin(angle), 0); +} + +//this returns the Spark +float getSpark(vec2 uv,vec2 center, float brightness, float size, float rotation) +{ + + //the size + size = clamp(size,0.001,1.0); + + uv = (uv + vec2(0.5)) ; //set center + uv = (uv - center) ;//Center UV coordinates, then scale to fit the star size + + //scale + uv = uv * 2.0 -1.0; + uv /= mix(vec2(1.0,1.0), vec2(0.0,0.0), vec2(1.0 - size)); + uv = uv * 0.5 + 0.5; + + uv = rotate(uv, rotation, vec2(0.5)); + + + //the brightness of the spark + brightness = clamp(brightness,0.001,1.0); + float bn = mix(0.0,0.07,brightness); //recalculate size + + + //this is basically the brightness + float p = mix(-1.0,1000.0,easeInExpo(bn)); + + float m = mix( + 0.0, + 1.0, + clamp( + pow(abs(uv.x-0.5)*2.0,p) + pow(abs(uv.y-0.5)*2.0,p),0.0,1.0 + ) + ); + + //calcuate and return this mask + float mask = easeInSine(1.0 - (m - bn)) - 0.004 ; + mask = clamp(mask,0.0,1.0); + return mask; + +} + + +//this was lifted from aura-glow +float getMask(float t) +{ + + // Calculate the aspect ratio of the render area + float aspect = uSize.x / uSize.y; + + //standard uv + vec2 uv = iTexCoord.st; + + // tuv is for when progress is near 0 + vec2 tuv = uv; + tuv -= 0.5; // Shift UV coordinates to center (from [-0.5 to 0.5]) + tuv.x *= aspect; // Scale x-coordinate to match aspect ratio + tuv += 0.5; // Shift UV coordinates back (from [0 to 1]) + + //mixing the UVs + uv = mix(tuv,uv,t); + + // this controls the shape + // -1.0 would be a diamond-ish + // 0.0 would be a rounded diamond + // 1.0 would be a circle + // 2.0 will be sqircle + // 1000.0 will be very square + float p = mix(1.0,1000.0, + easeInExpo(t) + ); + + //this will be used later to make a mask + float m = mix( + 0.0, + 1.0, + clamp( + pow(abs(uv.x-0.5)*2.0,p) + pow(abs(uv.y-0.5)*2.0,p),0.0,1.0 + ) + ); + + //this is the mask + //float mask = (m > t) ? 0.0 : 1.0 ; + float mask = (m > t) ? (1.0 - (m - t)) : 1.0 ; + mask = clamp(mask,0.0,1.0); + + return mask; +} + // A simple blur function vec4 blur(vec2 uv, float radius, float samples) { // Initialize the color accumulator to zero. vec4 color = vec4(0.0); - // Define a constant for 2 * PI (tau), which represents a full circle in radians. - const float tau = 6.28318530718; + // Number of directions for sampling around the circle. const float directions = 15.0; @@ -66,15 +201,299 @@ vec4 blur(vec2 uv, float radius, float samples) { } +//fades out at 0 and 1 ...based on the power +// 1| __________ +// | / \ +// | / \ +// | / \ +// |/ \ +// 0|0.................1 +/* +graph above ... where t is close to 0, or 1 the result will fade to zero +i.e. this is just the function of power(x,p) shifted +where x is time, and p is 2.0,4.0,8.0,10.0 ... or any positive even number +*/ +float FadeInOut(float t, float power) +{ + float s = -1.0 * pow((t-0.5)/(0.5),power)+1.0; + s = clamp(s,0.0,1.0); + return s; +} + +float getSparks(float t) +{ + + + //the UV for this function + float aspect = uSize.x / uSize.y; + vec2 uv = iTexCoord.st * vec2(aspect,1.0); + + float result = 0.0; + + + for (float i = 0.0; i < uSparkCount ; ++i) + { + + vec4 v4 = hash41( i * uSeed.x); + + + // float speed = (1.0 - t) ;//* v4.y; + + //the X and Y position ... at the end + vec3 pos = getPosByAngle( (i/uSparkCount) * tau + (v4.x * 0.3) ); + + //the distance the spark will travel + float d = mix(0.33,0.34,v4.z) ; + d = mix( + uSparkStartEnd.x + (v4.z * uSparkOffset), + uSparkStartEnd.y - (v4.y * uSparkOffset), + (1.0 - t) + ); + + float s = getSpark( + uv, + vec2(0.5 * aspect,0.5) + ( pos.xy * d ), //position (x, y) + FadeInOut(t,8.0) * 0.9 ,//Brightness + FadeInOut(t,8.0) * (v4.w * 0.5) ,//Size + 0.0 //rotation + ); + + result += s; + + } + + + // result = pow(result,1.0); + + result *= FadeInOut(iTexCoord.s,8.0); + result *= FadeInOut(iTexCoord.t,8.0); + + return clamp(result,0.0,1.0); + +} + + +//returns the particle's color +vec4 getParticleColors(float v, float alpha) { + // Clamp v to ensure it's in [0.0, 1.0] + v = clamp(v, 0.0, 1.0); + + // Define steps for color interpolation + float steps[6]; + steps[0] = 0.0; + steps[1] = 0.1666; + steps[2] = 0.3332; + steps[3] = 0.4998; + steps[4] = 0.6664; + steps[5] = 0.8330; + + // Define color values + vec4 colors[6]; + colors[0] = uParticleColor0 ; + colors[1] = uParticleColor1 ; + colors[2] = uParticleColor2 ; + colors[3] = uParticleColor3 ; + colors[4] = uParticleColor4 ; + colors[5] = uParticleColor5 ; + + // Assign alpha values + for (int i = 0; i < 6; ++i) { + colors[i].a = alpha * colors[i].a; + } + + // Handle edge cases + if (v <= steps[0]) { + return colors[0]; + } + if (v >= steps[5]) { + return colors[5]; + } + + // Find the correct interpolation segment + for (int i = 0; i < 5; ++i) { + if (v <= steps[i + 1]) { + float t = (v - steps[i]) / (steps[i + 1] - steps[i]); + return mix(colors[i], colors[i + 1], t); + } + } + + // Fallback (should never be reached) + return vec4(0.0, 0.0, 0.0, 1.0); +} + + +vec4 getStarColors(float v, float alpha) { + // Clamp v to ensure it's in [0.0, 1.0] + v = clamp(v, 0.0, 1.0); + + // Define steps for color interpolation + float steps[6]; + steps[0] = 0.0; + steps[1] = 0.1666; + steps[2] = 0.3332; + steps[3] = 0.4998; + steps[4] = 0.6664; + steps[5] = 0.8330; + + // Define color values + vec4 colors[6]; + colors[0] = uStarColor0 ; + colors[1] = uStarColor1 ; + colors[2] = uStarColor2 ; + colors[3] = uStarColor3 ; + colors[4] = uStarColor4 ; + colors[5] = uStarColor5 ; + + // Assign alpha values + for (int i = 0; i < 6; ++i) { + colors[i].a = alpha * colors[i].a; + } + + // Handle edge cases + if (v <= steps[0]) { + return colors[0]; + } + if (v >= steps[5]) { + return colors[5]; + } + + // Find the correct interpolation segment + for (int i = 0; i < 5; ++i) { + if (v <= steps[i + 1]) { + float t = (v - steps[i]) / (steps[i + 1] - steps[i]); + return mix(colors[i], colors[i + 1], t); + } + } + + // Fallback (should never be reached) + return vec4(0.0, 0.0, 0.0, 1.0); +} + + + + +//gets the mask of a Star +float getStar(vec2 uv, vec2 center, float npoints, float radiusRatio, float size, float rotation) +{ + + float radiusMax = 1.0; + float radiusMin = radiusMax * radiusRatio; + + float starangle = 2.0 * PI / npoints; // Angle between points on the star + + // Offset rotation to ensure one point is always up when rotation = 0 + rotation += PI / 2.0 - starangle / 1.0; + + // Define the positions for the outer and inner points of the star's initial angle, rotated by `rotation` + vec3 p0 = (radiusMax * size) * getPosByAngle(rotation); // Outer point, rotated by `rotation` + vec3 p1 = (radiusMin * size) * getPosByAngle(starangle + rotation); // Inner point, also rotated + + // Calculate the position of the current fragment relative to the star's center + vec2 curPosuv = (uv - center); // Center UV coordinates, then scale to fit the star size + float curRadius = length(curPosuv); // Radius from center, no need to scale further + float curPosAngle = atan(curPosuv.y, curPosuv.x) - rotation; // Calculate angle and adjust by `rotation` + + // Determine the fractional position within the current star segment + float a = fract(curPosAngle / starangle); // Fractional angle position within one segment + if (a >= 0.5) + a = 1.0 - a; // Ensure we are within the first half of the segment (symmetry) + + // Calculate the current point on the star segment, applying rotation + a = a * starangle; // Actual angle for this position on the segment + vec3 curPos = curRadius * getPosByAngle(a + rotation); // Final position, rotated + + // Calculate directions for edge detection using cross product + vec3 dir0 = p1 - p0; // Vector from outer to inner point + vec3 dir1 = curPos - p0; // Vector from outer point to current position + + // Use cross product to determine if `curPos` is inside the star's edge + return step(0.0, cross(dir0, dir1).z); // Returns 1.0 if inside, 0.0 if outside (solid edge) +} + + +float XYtoAngle(vec2 XY) +{ + return atan(XY.y, XY.x); +} + + +vec4 getStars(float t) +{ + + //the UV for this function + float aspect = uSize.x / uSize.y; + vec2 uv = iTexCoord.st * vec2(aspect,1.0); + + float result = 0.0; + + + for (float i = 0.0; i < uStarCount ; ++i) + { + + vec4 v4 = hash41( i * uSeed.x); + + //the X and Y position ... at the end + vec3 pos = getPosByAngle( (i/uStarCount) * tau + (uStarRot * tau * t) ); + + //the distance the spark will travel + float d = mix(0.33,0.34,v4.z) ; + d = mix( + uStarStartEnd.x , + uStarStartEnd.y , + (1.0 - t) + ); + + + float s = getStar( + uv, + vec2(0.5 * aspect,0.5) + ( pos.xy * d ), //position (x, y) + 5.0, //npoints + 0.5, //Ratio + FadeInOut(t,4.0) * uStarSize,//Size + PI //rotation + ); + + result += s; + + } + + result *= FadeInOut(iTexCoord.s,8.0); + result *= FadeInOut(iTexCoord.t,8.0); + result = clamp(result,0.0,1.0); + + + vec4 color = getStarColors( + (XYtoAngle(iTexCoord.st * 2.0 - 1.0) + PI) / tau + , 1.0); + + return vec4(color.rgb,result); + +} + + + +//gets the particles +vec4 getParticles(float alpha) +{ + vec2 uv = iTexCoord.st; + + float particles = pow((simplex3D(vec3(uv * 50.0, 10.0 * uProgress ))), 3.0); + + float pc = pow((simplex3D(vec3(uv * 50, 10.0 * uProgress ))), 1.0); + vec4 particleColor = getParticleColors(pc,1.0); + + + particles *= alpha; + + return vec4(particleColor.rgb,particles); +} + void main() { // Calculate the progression value based on the animation direction. // If opening, use uProgress as-is; if closing, invert the progression. float progress = uForOpening ? 1.0 - uProgress : uProgress ; - //r is for random .. 4 random numbers between -1.0 and 1.0 - vec4 r = hash42(iTexCoord.st * progress * 0.1) * 2.0 - vec4(0.5); - //zero to one... mostly one float ztomo = remap( progress, @@ -83,7 +502,6 @@ void main() { ); ztomo = easeInOutSine(ztomo); - //out Expo float oExpo = easeOutExpo(progress); float iExpo = easeInExpo(progress); @@ -92,24 +510,27 @@ void main() { vec2 uv = iTexCoord.st; - // change the center - uv = uv * 2.0 - 1.0; + // // change the center + // uv = uv * 2.0 - 1.0; + // //scale + // uv /= ioSine_r; + // //re-center + // uv = uv * 0.5 + 0.5; - //scale - uv /= ioSine_r; - - //re-center - uv = uv * 0.5 + 0.5; - - // uv.x -= simplex3D(r.xyz * 50.0) * 0.1; - // uv.y -= simplex3D(r.xyz * 50.0) * 0.1; - - // uv.x -= sin(progress) - -//get color + //get color vec4 oColor = blur(uv, ztomo * 100.0,uBlurQuality); - oColor.a *= ioSine_r; + oColor.a *= getMask(1.0 - ioSine); + //get and apply particles + vec4 particles = getParticles(oColor.a); + oColor = mix(oColor,particles,ztomo); + + //get and apply sparks + float sparks = getSparks(progress); + oColor = alphaOver(oColor, vec4(1.0,1.0,1.0,sparks)); + + + oColor = alphaOver(oColor, getStars(mix(0.0001,0.999,progress))); setOutputColor(oColor); diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml index cf39324..20bcd75 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml @@ -1096,6 +1096,12 @@ SPDX-License-Identifier: CC0-1.0 The time the Team Rocket effect takes. + + 0.5 + Window vs Sparkle split + Window vs Sparkle split + + 0.0 Team Rocket X diff --git a/src/effects/SimpleFade.js b/src/effects/SimpleFade.js index ad50b01..f4abb4b 100644 --- a/src/effects/SimpleFade.js +++ b/src/effects/SimpleFade.js @@ -39,16 +39,17 @@ export default class Effect { constructor() { this.shaderFactory = new ShaderFactory(Effect.getNick(), (shader) => { // Store uniform locations of newly created shaders. - // shader._uFadeWidth = shader.get_uniform_location('uFadeWidth'); + // shader._uFadeWidth = shader.get_uniform_location('uFadeWidth'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { + shader.connect('begin-animation', + (shader, settings) => { - // shader.set_uniform_float(shader._uFadeWidth, 1, [ - // settings.get_double('simple-fade-width'), - // ]); + // shader.set_uniform_float(shader._uFadeWidth, 1, [ + // settings.get_double('simple-fade-width'), + // ]); - }); + }); }); }