From 86caa88f5473875138e0d612212e151c16cf1000 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 9 Feb 2025 05:55:14 +0100 Subject: [PATCH] :wrench: Streamline team-rocket effect --- resources/shaders/team-rocket.frag | 186 ++++++++++++----------------- src/effects/TeamRocket.js | 39 ++---- 2 files changed, 86 insertions(+), 139 deletions(-) diff --git a/resources/shaders/team-rocket.frag b/resources/shaders/team-rocket.frag index 515c800..33b64fb 100644 --- a/resources/shaders/team-rocket.frag +++ b/resources/shaders/team-rocket.frag @@ -30,114 +30,90 @@ // vec4 getInputColor(vec2 coords) // void setOutputColor(vec4 outColor) -// The width of the fading effect is loaded from the settings. +// window time ... how we split the time between the window and the sparkle/star +uniform float uWT; +uniform float uXpos; // the Xposition of the star +uniform float uYpos; // the Yposition of the star +uniform float uSparkleRot; // the rotation of the star +uniform float uSparkleSize; // the size of the star +uniform bool uWinRot; // window rotation... but it's more of a warp +uniform vec2 uSeed; // and random numbers -//variables -uniform float uWT; //window time ... how we split the time between the window and the sparkle/star -uniform float uXpos; // the Xposition of the star -uniform float uYpos; // the Yposition of the star -uniform float uSparkleRot; //the rotation of the star -uniform float uSparkleSize; // the size of the star -uniform bool uWinRot; //window rotation... but it's more of a warp -uniform vec2 uSeed; // and random numbers - - -//use to scale the window -vec2 scaleUV(vec2 uv, vec2 scale, vec2 centerOffset) -{ +// Used to scale the window. +vec2 scaleUV(vec2 uv, vec2 scale, vec2 centerOffset) { // Put texture coordinate origin to center of window. uv -= centerOffset; uv = uv * 2.0 - 1.0; - //scale - uv /= mix(vec2(1.0,1.0), vec2(0.0,0.0), scale); + // scale + uv /= mix(vec2(1.0, 1.0), vec2(0.0, 0.0), scale); // scale from center uv = uv * 0.5 + 0.5; - return uv; } +// This returns the Spark. +float getSpark(vec2 uv, vec2 center, float brightness, float size, float rotation) { + brightness = clamp(brightness, 0.001, 1.0); + size = clamp(size, 0.001, 1.0); -//this returns the Spark -float getSpark(vec2 uv, vec2 center, float brightness, float size, float rotation) -{ - //the brightness of the spark - brightness = clamp(brightness,0.001,1.0); - //the size - size = clamp(size,0.001,1.0); + float bn = mix(0.0, 0.07, brightness); // recalculate size - float bn = mix(0.0,0.07,brightness); //recalculate size - - uv = (uv + vec2(0.5)) ; //set center - uv = (uv - center) ;//Center UV coordinates, then scale to fit the star size + uv = (uv + vec2(0.5)); // set center + uv = (uv - center); // Center UV coordinates, then scale to fit the star size uv = scaleUV(uv, vec2(1.0 - size), vec2(0.0)); - uv = rotate(uv, rotation, vec2(0.5)); //rotate the UV + uv = rotate(uv, rotation, vec2(0.5)); // rotate the UV - //this is basically the brightness - float p = mix(-1.0,1000.0,easeInExpo(bn)); + // 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 - ) - ); + 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); + // calcuate and return this mask + float mask = easeInSine(1.0 - (m - bn)) - 0.004; + mask = clamp(mask, 0.0, 1.0); return mask; - } - -//fades out at 0 and 1 ...based on the power -// 1| __________ -// | / \ -// | / \ -// | / \ -// |/ \ -// 0|0.................1 +// 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); +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; } -//2x pi ... don't think too much about it +// 2x pi ... don't think too much about it float TAU = 6.28; 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 ; + float progress = uForOpening ? 1.0 - uProgress : uProgress; // scale progress ... the first half of the animation - float scalep = remap( - progress, - 0.0,uWT+0.1, - 0.0,1.0 - ); + float scalep = remap(progress, 0.0, uWT + 0.1, 0.0, 1.0); // scalep = easeInOutSine(scalep); scalep = easeOutQuad(scalep); - // sparkle progress ... the second half of the animation - float sparkp = remap( - progress, - uWT-0.1,1.0, - 0.0,1.0 - ); - sparkp = easeInOutSine(sparkp); + // sparkle progress ... the second half of the animation + float sparkp = remap(progress, uWT - 0.1, 1.0, 0.0, 1.0); + sparkp = easeInOutSine(sparkp); /* the window will scale between 0.0 and 0.6 (of the progress) @@ -146,69 +122,57 @@ void main() { */ // // this is the offset of the window... don't let them go too far each way - vec2 offset = vec2(uXpos,uYpos*-1.0) * 0.20; - vec2 scaleOffset = mix( - vec2(0.0), - vec2(uXpos,uYpos*-1.0) * 0.50, - scalep - ); + vec2 offset = vec2(uXpos, uYpos * -1.0) * 0.20; + vec2 scaleOffset = mix(vec2(0.0), vec2(uXpos, uYpos * -1.0) * 0.50, scalep); - //the UV for this function + // the UV for this function float aspect = uSize.x / uSize.y; - vec2 uv = iTexCoord.st * vec2(aspect,1.0); - - //get and adjust + vec2 uv = iTexCoord.st * vec2(aspect, 1.0); + + // get and adjust vec2 uv2 = iTexCoord.st; - uv2 = uv2 * 2.0 - 1.0; + uv2 = uv2 * 2.0 - 1.0; - //offset - uv2 -= ( scaleOffset/ vec2(aspect,1.0) ) *scalep; + // offset + uv2 -= (scaleOffset / vec2(aspect, 1.0)) * scalep; - //scale + // scale uv2 /= mix(1.0, 0.0, scalep); - //rotation and if we are gonna rotate or not + // rotation and if we are gonna rotate or not vec3 rot = vec3(0.0); - if (uWinRot) - { + if (uWinRot) { rot = hash32(uSeed); rot *= 2.0; rot -= 1.0; rot *= 0.1; } - //rotate around x, y , and z + // rotate around x, y , and z uv2.x /= mix(1.0, rot.x * TAU * uv2.y, scalep); uv2.y /= mix(1.0, rot.y * TAU * uv2.x, scalep); - uv2 = rotate(uv2,rot.z*TAU*scalep); - - //re-center + uv2 = rotate(uv2, rot.z * TAU * scalep); + + // re-center uv2 = uv2 * 0.5 + 0.5; - //gets the window - vec4 oColor = getInputColor( uv2) ; + // gets the window + vec4 oColor = getInputColor(uv2); - //the sparksize will bet between 25.0 and 50.0 - float size = mix(25.0,50.0,uSparkleSize); + // the sparksize will bet between 25.0 and 50.0 + float size = mix(25.0, 50.0, uSparkleSize); - //get the sparkle - float sparkle = getSpark( - uv, - offset + vec2(0.5 * aspect,0.5), - FadeInOut(sparkp,2) * uSparkleSize, - FadeInOut(sparkp,2) * size, - sparkp * TAU * float(uSparkleRot) - ); - //fade out at the edges - sparkle *= FadeInOut(iTexCoord.t,8); - sparkle *= FadeInOut(iTexCoord.s,8); - - //set it to the results - oColor = alphaOver( - oColor, - vec4(1.0,1.0,1.0,sparkle) - ); + // get the sparkle + float sparkle = + getSpark(uv, offset + vec2(0.5 * aspect, 0.5), FadeInOut(sparkp, 2) * uSparkleSize, + FadeInOut(sparkp, 2) * size, sparkp * TAU * float(uSparkleRot)); + // fade out at the edges + sparkle *= FadeInOut(iTexCoord.t, 8); + sparkle *= FadeInOut(iTexCoord.s, 8); - //output the color + // set it to the results + oColor = alphaOver(oColor, vec4(1.0, 1.0, 1.0, sparkle)); + + // output the color setOutputColor(oColor); } \ No newline at end of file diff --git a/src/effects/TeamRocket.js b/src/effects/TeamRocket.js index de70709..632b8b3 100644 --- a/src/effects/TeamRocket.js +++ b/src/effects/TeamRocket.js @@ -50,32 +50,17 @@ export default class Effect { // Write all uniform values at the start of each animation. shader.connect('begin-animation', (shader, settings) => { - shader.set_uniform_float(shader._uWT, 1, [ - settings.get_double('team-rocket-window-time'), - ]); - - shader.set_uniform_float(shader._uXpos, 1, [ - settings.get_double('team-rocket-x'), - ]); - - shader.set_uniform_float(shader._uYpos, 1, [ - settings.get_double('team-rocket-y'), - ]); - - shader.set_uniform_float(shader._uWinRot, 1, - [settings.get_boolean('team-rocket-win-rot')]); - - shader.set_uniform_float(shader._uSparkleRot, 1, [ - settings.get_double('team-rocket-sparkle-rot'), - ]); - - shader.set_uniform_float(shader._uSparkleSize, 1, [ - settings.get_double('team-rocket-sparkle-size'), - ]); - - // this will be used with a has function to get a random number // clang-format off - shader.set_uniform_float(shader._uSeed, 2, [Math.random(), Math.random()]); + shader.set_uniform_float(shader._uWT, 1, [settings.get_double('team-rocket-window-time')]); + shader.set_uniform_float(shader._uXpos, 1, [settings.get_double('team-rocket-x')]); + shader.set_uniform_float(shader._uYpos, 1, [settings.get_double('team-rocket-y')]); + shader.set_uniform_float(shader._uWinRot, 1, [settings.get_boolean('team-rocket-win-rot')]); + shader.set_uniform_float(shader._uSparkleRot, 1, [settings.get_double('team-rocket-sparkle-rot')]); + shader.set_uniform_float(shader._uSparkleSize, 1, [settings.get_double('team-rocket-sparkle-size')]); + // clang-format on + + // This will be used with a hash function to get a random number. + shader.set_uniform_float(shader._uSeed, 2, [Math.random(), Math.random()]); }); }); } @@ -107,8 +92,6 @@ export default class Effect { // This is called by the preferences dialog whenever a new effect profile is loaded. It // binds all user interface elements to the respective settings keys of the profile. static bindPreferences(dialog) { - // Empty for now... Code is added here later in the tutorial! - dialog.bindAdjustment('team-rocket-animation-time'); dialog.bindAdjustment('team-rocket-window-time'); dialog.bindAdjustment('team-rocket-x'); @@ -128,4 +111,4 @@ export default class Effect { static getActorScale(settings, forOpening, actor) { return {x: 1.0, y: 1.0}; } -} \ No newline at end of file +}