🔧 Streamline team-rocket effect

This commit is contained in:
Simon Schneegans
2025-02-09 05:55:14 +01:00
parent ba8284a99a
commit 86caa88f54
2 changed files with 86 additions and 139 deletions
+75 -111
View File
@@ -30,114 +30,90 @@
// vec4 getInputColor(vec2 coords) // vec4 getInputColor(vec2 coords)
// void setOutputColor(vec4 outColor) // 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 // Used to scale the window.
uniform float uWT; //window time ... how we split the time between the window and the sparkle/star vec2 scaleUV(vec2 uv, vec2 scale, vec2 centerOffset) {
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)
{
// Put texture coordinate origin to center of window. // Put texture coordinate origin to center of window.
uv -= centerOffset; uv -= centerOffset;
uv = uv * 2.0 - 1.0; uv = uv * 2.0 - 1.0;
//scale // scale
uv /= mix(vec2(1.0,1.0), vec2(0.0,0.0), scale); uv /= mix(vec2(1.0, 1.0), vec2(0.0, 0.0), scale);
// scale from center // scale from center
uv = uv * 0.5 + 0.5; uv = uv * 0.5 + 0.5;
return uv; 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 bn = mix(0.0, 0.07, brightness); // recalculate size
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 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 = 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 // this is basically the brightness
float p = mix(-1.0,1000.0,easeInExpo(bn)); float p = mix(-1.0, 1000.0, easeInExpo(bn));
float m = mix( float m =
0.0, mix(0.0, 1.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));
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 // calcuate and return this mask
float mask = easeInSine(1.0 - (m - bn)) - 0.004 ; float mask = easeInSine(1.0 - (m - bn)) - 0.004;
mask = clamp(mask,0.0,1.0); mask = clamp(mask, 0.0, 1.0);
return mask; return mask;
} }
// fades out at 0 and 1 ...based on the power
//fades out at 0 and 1 ...based on the power // 1| __________
// 1| __________ // | / \
// | / \ // | / \
// | / \ // | / \
// | / \ // | / \
// |/ \ // 0| 0.................1
// 0|0.................1
/* /*
graph above ... where t is close to 0, or 1 the result will fade to zero 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 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 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 FadeInOut(float t, float power) {
{ float s = -1.0 * pow((t - 0.5) / (0.5), power) + 1.0;
float s = -1.0 * pow((t-0.5)/(0.5),power)+1.0; s = clamp(s, 0.0, 1.0);
s = clamp(s,0.0,1.0);
return s; return s;
} }
//2x pi ... don't think too much about it // 2x pi ... don't think too much about it
float TAU = 6.28; float TAU = 6.28;
void main() { void main() {
// Calculate the progression value based on the animation direction. // Calculate the progression value based on the animation direction.
// If opening, use uProgress as-is; if closing, invert the progression. // 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 // scale progress ... the first half of the animation
float scalep = remap( float scalep = remap(progress, 0.0, uWT + 0.1, 0.0, 1.0);
progress,
0.0,uWT+0.1,
0.0,1.0
);
// scalep = easeInOutSine(scalep); // scalep = easeInOutSine(scalep);
scalep = easeOutQuad(scalep); scalep = easeOutQuad(scalep);
// sparkle progress ... the second half of the animation // sparkle progress ... the second half of the animation
float sparkp = remap( float sparkp = remap(progress, uWT - 0.1, 1.0, 0.0, 1.0);
progress, sparkp = easeInOutSine(sparkp);
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) 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 // // 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 offset = vec2(uXpos, uYpos * -1.0) * 0.20;
vec2 scaleOffset = mix( vec2 scaleOffset = mix(vec2(0.0), vec2(uXpos, uYpos * -1.0) * 0.50, scalep);
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; float aspect = uSize.x / uSize.y;
vec2 uv = iTexCoord.st * vec2(aspect,1.0); vec2 uv = iTexCoord.st * vec2(aspect, 1.0);
//get and adjust // get and adjust
vec2 uv2 = iTexCoord.st; vec2 uv2 = iTexCoord.st;
uv2 = uv2 * 2.0 - 1.0; uv2 = uv2 * 2.0 - 1.0;
//offset // offset
uv2 -= ( scaleOffset/ vec2(aspect,1.0) ) *scalep; uv2 -= (scaleOffset / vec2(aspect, 1.0)) * scalep;
//scale // scale
uv2 /= mix(1.0, 0.0, scalep); 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); vec3 rot = vec3(0.0);
if (uWinRot) if (uWinRot) {
{
rot = hash32(uSeed); rot = hash32(uSeed);
rot *= 2.0; rot *= 2.0;
rot -= 1.0; rot -= 1.0;
rot *= 0.1; 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.x /= mix(1.0, rot.x * TAU * uv2.y, scalep);
uv2.y /= mix(1.0, rot.y * TAU * uv2.x, scalep); uv2.y /= mix(1.0, rot.y * TAU * uv2.x, scalep);
uv2 = rotate(uv2,rot.z*TAU*scalep); uv2 = rotate(uv2, rot.z * TAU * scalep);
//re-center // re-center
uv2 = uv2 * 0.5 + 0.5; uv2 = uv2 * 0.5 + 0.5;
//gets the window // gets the window
vec4 oColor = getInputColor( uv2) ; vec4 oColor = getInputColor(uv2);
//the sparksize will bet between 25.0 and 50.0 // the sparksize will bet between 25.0 and 50.0
float size = mix(25.0,50.0,uSparkleSize); float size = mix(25.0, 50.0, uSparkleSize);
//get the sparkle // get the sparkle
float sparkle = getSpark( float sparkle =
uv, getSpark(uv, offset + vec2(0.5 * aspect, 0.5), FadeInOut(sparkp, 2) * uSparkleSize,
offset + vec2(0.5 * aspect,0.5), FadeInOut(sparkp, 2) * size, sparkp * TAU * float(uSparkleRot));
FadeInOut(sparkp,2) * uSparkleSize, // fade out at the edges
FadeInOut(sparkp,2) * size, sparkle *= FadeInOut(iTexCoord.t, 8);
sparkp * TAU * float(uSparkleRot) sparkle *= FadeInOut(iTexCoord.s, 8);
);
//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)
);
//output the color // set it to the results
oColor = alphaOver(oColor, vec4(1.0, 1.0, 1.0, sparkle));
// output the color
setOutputColor(oColor); setOutputColor(oColor);
} }
+11 -28
View File
@@ -50,32 +50,17 @@ export default class Effect {
// Write all uniform values at the start of each animation. // 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._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 // 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 // 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. // binds all user interface elements to the respective settings keys of the profile.
static bindPreferences(dialog) { static bindPreferences(dialog) {
// Empty for now... Code is added here later in the tutorial!
dialog.bindAdjustment('team-rocket-animation-time'); dialog.bindAdjustment('team-rocket-animation-time');
dialog.bindAdjustment('team-rocket-window-time'); dialog.bindAdjustment('team-rocket-window-time');
dialog.bindAdjustment('team-rocket-x'); dialog.bindAdjustment('team-rocket-x');
@@ -128,4 +111,4 @@ export default class Effect {
static getActorScale(settings, forOpening, actor) { static getActorScale(settings, forOpening, actor) {
return {x: 1.0, y: 1.0}; return {x: 1.0, y: 1.0};
} }
} }