diff --git a/assets/matrixFont.svg b/assets/matrixFont.svg
new file mode 100644
index 0000000..f612709
--- /dev/null
+++ b/assets/matrixFont.svg
@@ -0,0 +1,374 @@
+
+
+
+
diff --git a/docs/changelog.md b/docs/changelog.md
index 3a5a52f..f0bc7a9 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -5,9 +5,13 @@
**Release Date:** TBD
#### New Features
+
+* Added a new Matrix shader which dissolves your windows in a shower of green letters. You can switch between the fire and the matrix shader in the settings. Sadly, this effect cannot be available under GNOME 3.3x as it was apparently impossible to set textures for a `Clutter.ShaderEffect` in GJS back then.
+
#### Other Enhancements
* Refactored the code a lot to make it easier to add new shader effects in the future.
+* Tweaked timing of the fire shader. Previously, the fire became invisible quite quickly. Due to this new animation timing, the default animation time has been reduced to 1500 ms.
## [Burn My Window 3](https://github.com/schneegans/Burn-My-Windows/releases/tag/v3)
diff --git a/extension.js b/extension.js
index 957c471..a85162b 100644
--- a/extension.js
+++ b/extension.js
@@ -13,7 +13,7 @@
'use strict';
-const {Clutter, Meta} = imports.gi;
+const {Clutter, Gio, Meta} = imports.gi;
const Workspace = imports.ui.workspace.Workspace;
const WindowManager = imports.ui.windowManager.WindowManager;
@@ -23,6 +23,7 @@ const ExtensionUtils = imports.misc.extensionUtils;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const utils = Me.imports.src.common.utils;
const FireShader = Me.imports.src.extension.FireShader.FireShader;
+const MatrixShader = Me.imports.src.extension.MatrixShader.MatrixShader;
//////////////////////////////////////////////////////////////////////////////////////////
// This extensions modifies the window-close animation to look like the window was set //
@@ -39,6 +40,10 @@ class Extension {
// from GNOME Tweaks, when you log in or when the screen is unlocked.
enable() {
+ // Load all of our resources.
+ this._resources = Gio.Resource.load(Me.path + '/resources/burn-my-windows.gresource');
+ Gio.resources_register(this._resources);
+
// Store a reference to the settings object.
this._settings = ExtensionUtils.getSettings();
@@ -141,17 +146,27 @@ class Extension {
tweakTransition('scale-x', 1);
tweakTransition('scale-y', 1);
- // Instead, we add a cool shader to our window actor!
- const shader = new FireShader(this._settings);
- actor.add_effect(shader);
+ let shader = null;
- // Update uniforms at each frame.
- transition.connect('new-frame', (t) => {
- shader.set_uniform_value('uProgress', t.get_progress());
- shader.set_uniform_value('uTime', 0.001 * t.get_elapsed_time());
- shader.set_uniform_value('uSizeX', actor.width);
- shader.set_uniform_value('uSizeY', actor.height);
- });
+ // Add a cool shader to our window actor!
+ const mode = this._settings.get_enum('close-animation');
+ if (mode == 1) {
+ shader = new FireShader(this._settings);
+ } else if (mode == 2) {
+ shader = new MatrixShader(this._settings);
+ }
+
+ if (shader) {
+ actor.add_effect(shader);
+
+ // Update uniforms at each frame.
+ transition.connect('new-frame', (t) => {
+ shader.set_uniform_value('uProgress', t.get_progress());
+ shader.set_uniform_value('uTime', 0.001 * t.get_elapsed_time());
+ shader.set_uniform_value('uSizeX', actor.width);
+ shader.set_uniform_value('uSizeY', actor.height);
+ });
+ }
});
}
@@ -159,6 +174,9 @@ class Extension {
// Tweaks, when you log out or when the screen locks.
disable() {
+ // Unregister our resources.
+ Gio.resources_unregister(this._resources);
+
// Restore the original behavior.
global.window_manager.disconnect(this._destroyConnection);
diff --git a/prefs.js b/prefs.js
index 0d7eaee..20961b0 100644
--- a/prefs.js
+++ b/prefs.js
@@ -43,6 +43,7 @@ var PreferencesDialog = class PreferencesDialog {
this._settings = ExtensionUtils.getSettings();
// Bind all properties.
+ this._bindCombobox('close-animation');
this._bindAdjustment('destroy-animation-time');
this._bindSwitch('destroy-dialogs');
this._bindAdjustment('flame-movement-speed');
@@ -52,6 +53,10 @@ var PreferencesDialog = class PreferencesDialog {
this._bindColorButton('fire-color-3');
this._bindColorButton('fire-color-4');
this._bindColorButton('fire-color-5');
+ this._bindAdjustment('matrix-scale');
+ this._bindAdjustment('matrix-randomness');
+ this._bindColorButton('matrix-trail-color');
+ this._bindColorButton('matrix-tip-color');
// The fire-gradient-reset button needs to by bound explicitly.
this._builder.get_object('reset-fire-colors').connect('clicked', () => {
@@ -87,6 +92,12 @@ var PreferencesDialog = class PreferencesDialog {
// ----------------------------------------------------------------------- private stuff
+ // Connects a Gtk.ComboBox (or anything else which has an 'active-id' property) to a
+ // settings key. It also binds the corresponding reset button.
+ _bindCombobox(settingsKey) {
+ this._bind(settingsKey, 'active-id');
+ }
+
// Connects a Gtk.Adjustment (or anything else which has a 'value' property) to a
// settings key. It also binds the corresponding reset button.
_bindAdjustment(settingsKey) {
@@ -100,36 +111,50 @@ var PreferencesDialog = class PreferencesDialog {
}
// Colors are stored as strings like 'rgb(1, 0.5, 0)'. As Gio.Settings.bind_with_mapping
- // is not available yet, we need to do the color conversion manually.
+ // is not available yet, we need to do the color conversion manually. It also binds the
+ // corresponding reset button.
_bindColorButton(settingsKey) {
const button = this._builder.get_object(settingsKey);
- // Update the settings when the color is modified.
- button.connect('color-set', () => {
- this._settings.set_string(settingsKey, button.get_rgba().to_string());
- });
+ if (button) {
- // Update the button state when the settings change.
- const settingSignalHandler = () => {
- const rgba = new Gdk.RGBA();
- rgba.parse(this._settings.get_string(settingsKey));
- button.rgba = rgba;
- };
+ // Update the settings when the color is modified.
+ button.connect('color-set', () => {
+ this._settings.set_string(settingsKey, button.get_rgba().to_string());
+ });
- this._settings.connect('changed::' + settingsKey, settingSignalHandler);
+ // Update the button state when the settings change.
+ const settingSignalHandler = () => {
+ const rgba = new Gdk.RGBA();
+ rgba.parse(this._settings.get_string(settingsKey));
+ button.rgba = rgba;
+ };
- // Initialize the button with the state in the settings.
- settingSignalHandler();
+ this._settings.connect('changed::' + settingsKey, settingSignalHandler);
+
+ // Initialize the button with the state in the settings.
+ settingSignalHandler();
+ }
+
+ this._bindResetButton(settingsKey);
}
// Connects any widget's property to a settings key. The widget must have the same ID as
// the settings key. It also binds the corresponding reset button.
_bind(settingsKey, property) {
- this._settings.bind(
- settingsKey, this._builder.get_object(settingsKey), property,
- Gio.SettingsBindFlags.DEFAULT);
+ const object = this._builder.get_object(settingsKey);
+ if (object) {
+ this._settings.bind(settingsKey, object, property, Gio.SettingsBindFlags.DEFAULT);
+ }
+
+ this._bindResetButton(settingsKey);
+ }
+
+ // Searches for a reset button for the given settings key and make it reset the settings
+ // key when clicked.
+ _bindResetButton(settingsKey) {
const resetButton = this._builder.get_object('reset-' + settingsKey);
if (resetButton) {
resetButton.connect('clicked', () => {
diff --git a/resources/img/matrixFont.png b/resources/img/matrixFont.png
new file mode 100644
index 0000000..4ec6a2d
Binary files /dev/null and b/resources/img/matrixFont.png differ
diff --git a/resources/ui/gtk3.ui b/resources/ui/gtk3.ui
index 3809546..cf5ac7f 100644
--- a/resources/ui/gtk3.ui
+++ b/resources/ui/gtk3.ui
@@ -2,6 +2,23 @@
+
+
+
+
+
+
diff --git a/resources/ui/gtk4.ui b/resources/ui/gtk4.ui
index e44b622..f7de86d 100644
--- a/resources/ui/gtk4.ui
+++ b/resources/ui/gtk4.ui
@@ -2,6 +2,23 @@
+
+
+
+
+
+
+
+
Fire
+
fire
+
+
+
Matrix
+
matrix
+
+
+
+
never200
@@ -42,6 +59,48 @@
+
+
+ 0
+
+
+
+
+ Close Window Animation
+ 0
+ start
+ center
+ 1
+
+
+
+
+ center
+ animation-mode-list
+ 1
+ fire
+
+
+
+ 0
+
+
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
0
@@ -134,7 +193,7 @@
10
- Fire Options
+ Fire Animation Options01
+
+
+
+
+
+
+
+
+
+ none
+ 1
+
+
+
+
+ 0
+
+
+
+
+ Scale
+ 0
+ start
+ center
+ 1
+
+
+
+
+ end
+ center
+ 1
+ 0
+ left
+ 300
+
+
+ 50
+ 5
+ 1
+ 5
+
+
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ Randomness
+ 0
+ start
+ center
+ 1
+
+
+
+
+ end
+ center
+ 1
+ 2
+ left
+ 300
+
+
+ 1.0
+ 0.0
+ 0.01
+ 0.1
+
+
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ Trail Color
+ 0
+ start
+ center
+ 1
+
+
+
+
+ 0
+ 1
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ Tip Color
+ 0
+ start
+ center
+ 1
+
+
+
+
+ 0
+ 1
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml
index 0ad1dc5..5947394 100644
--- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml
+++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml
@@ -1,10 +1,22 @@
+
+
+
+
+
+
+ "fire"
+ Close Animation
+ The animation used for window closing.
+
+
+
- 2000
+ 1500Destroy Animation TimeThe time it takes to burn the windows.
@@ -57,6 +69,31 @@
The fifth color of the fire gradient.
+
+
+ 20
+ Matrix Scale
+ The size of the matrix letters.
+
+
+
+ 1.0
+ Matrix Randomness
+ The randomness of the matrix effect.
+
+
+
+ "rgb(255, 255, 255)"
+ Matrix Tip Color
+ The color of the matrix trail tips.
+
+
+
+ "rgb(25, 255, 89)"
+ Matrix Trail Color
+ The color matrix trails.
+
+
\ No newline at end of file
diff --git a/src/extension/FireShader.js b/src/extension/FireShader.js
index e1af97c..9e9f81f 100644
--- a/src/extension/FireShader.js
+++ b/src/extension/FireShader.js
@@ -20,6 +20,10 @@ const Me = imports.misc.extensionUtils.getCurrentExtension();
const shaderSnippets = Me.imports.src.extension.shaderSnippets;
//////////////////////////////////////////////////////////////////////////////////////////
+// The FireShader uses a procedural gray-scale noise texture. This texture is moved //
+// vertically over time and mapped to a configurable color gradient. It is faded to //
+// transparency towards the edges of the window. In addition, there are a couple of //
+// moving gradients which fade-in or fade-out the fire effect. //
//////////////////////////////////////////////////////////////////////////////////////////
var FireShader = GObject.registerClass({Properties: {}, Signals: {}},
@@ -38,18 +42,16 @@ var FireShader = GObject.registerClass({Properties: {}, Signals: {}},
color.blue / 255}, ${color.alpha / 255})`);
}
-
this.set_shader_source(`
// Inject some common shader snippets.
${shaderSnippets.standardUniforms()}
${shaderSnippets.noise()}
- ${shaderSnippets.effectMask()}
// These may be configurable in the future.
const float EDGE_FADE = 70;
const float FADE_WIDTH = 0.1;
- const float HIDE_TIME = 0.2;
+ const float HIDE_TIME = 0.3;
const vec2 FIRE_SCALE = vec2(400, 600) * ${settings.get_double('flame-scale')};
const float FIRE_SPEED = ${settings.get_double('flame-movement-speed')};
@@ -78,7 +80,46 @@ var FireShader = GObject.registerClass({Properties: {}, Signals: {}},
return colors[4];
}
- void main(void) {
+ // This method requires the uniforms from standardUniforms() to be available.
+ // It returns two values: The first is an alpha value which can be used for the window
+ // texture. This gradually dissolves the window from top to bottom. The second can be used
+ // to mask any effect, it will be most opaque where the window is currently fading and
+ // gradually dissolve to zero over time.
+ // hideTime: A value in [0..1]. It determines the percentage of the animation which
+ // is spent for hiding the window. 1-hideTime will be spent thereafter for
+ // dissolving the effect mask.
+ // fadeWidth: The relative size of the window-hiding gradient in [0..1].
+ // edgeFadeWidth: The pixel width of the effect fading range at the edges of the window.
+ vec2 effectMask(float hideTime, float fadeWidth, float edgeFadeWidth) {
+ float burnProgress = clamp(uProgress/hideTime, 0, 1);
+ float afterBurnProgress = clamp((uProgress-hideTime)/(1-hideTime), 0, 1);
+
+ // Gradient from top to bottom.
+ float t = cogl_tex_coord_in[0].t * (1 - fadeWidth);
+
+ // Visible part of the window. Gradually dissolves towards the bottom.
+ float windowMask = 1 - clamp((burnProgress - t) / fadeWidth, 0, 1);
+
+ // Gradient from top burning window.
+ float effectMask = clamp(t*(1-windowMask)/burnProgress, 0, 1);
+
+ // Fade-out when the window burned down.
+ if (uProgress > hideTime) {
+ float fade = cos(afterBurnProgress*3.14159*0.5);
+ effectMask *= mix(1-t, 1, fade) * fade;
+ }
+
+ // Fade at window borders.
+ vec2 pos = cogl_tex_coord_in[0].st * vec2(uSizeX, uSizeY);
+ effectMask *= clamp(pos.x / edgeFadeWidth, 0, 1);
+ effectMask *= clamp(pos.y / edgeFadeWidth, 0, 1);
+ effectMask *= clamp((uSizeX - pos.x) / edgeFadeWidth, 0, 1);
+ effectMask *= clamp((uSizeY - pos.y) / edgeFadeWidth, 0, 1);
+
+ return vec2(windowMask, effectMask);
+ }
+
+ void main() {
// Get a noise value which moves vertically in time.
vec2 uv = cogl_tex_coord_in[0].st * vec2(uSizeX, uSizeY) / FIRE_SCALE;
diff --git a/src/extension/MatrixShader.js b/src/extension/MatrixShader.js
new file mode 100644
index 0000000..9275a89
--- /dev/null
+++ b/src/extension/MatrixShader.js
@@ -0,0 +1,145 @@
+//////////////////////////////////////////////////////////////////////////////////////////
+// ) ( //
+// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
+// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
+// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
+// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
+// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
+// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
+// |__/ //
+// Copyright (c) 2021 Simon Schneegans //
+// Released under the GPLv3 or later. See LICENSE file for details. //
+//////////////////////////////////////////////////////////////////////////////////////////
+
+'use strict';
+
+const {Clutter, GObject, GdkPixbuf, Cogl} = imports.gi;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Me = imports.misc.extensionUtils.getCurrentExtension();
+const shaderSnippets = Me.imports.src.extension.shaderSnippets;
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// The MatrixShader multiplies a grid of random letters with some gradients which are //
+// moving from top to bottom. The speed of the moving gradients is chosen randomly. //
+// Also, there is a random delay making the gradients not drop all at the same time. //
+// This effect is not available on GNOME 3.3x, due to the limitation described in the //
+// documentation of vfunc_paint_target further down in this file. //
+//////////////////////////////////////////////////////////////////////////////////////////
+
+var MatrixShader = GObject.registerClass({Properties: {}, Signals: {}},
+ class MatrixShader extends Clutter.ShaderEffect {
+ _init(settings) {
+ super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER});
+
+ // Load the font texture. As the shader is re-created for each window animation, this
+ // texture is also re-created each time. This could be improved in the future!
+ const fontData = GdkPixbuf.Pixbuf.new_from_resource('/img/matrixFont.png');
+ this._fontTexture = new Clutter.Image();
+ this._fontTexture.set_data(
+ fontData.get_pixels(),
+ fontData.has_alpha ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGB_888,
+ fontData.width, fontData.height, fontData.rowstride);
+
+ const trailColor =
+ Clutter.Color.from_string(settings.get_string('matrix-trail-color'))[1];
+ const tipColor =
+ Clutter.Color.from_string(settings.get_string('matrix-tip-color'))[1];
+
+ // This is partially based on https://www.shadertoy.com/view/ldccW4 (CC-BY-NC-SA).
+ this.set_shader_source(`
+
+ // Inject some common shader snippets.
+ ${shaderSnippets.standardUniforms()}
+ ${shaderSnippets.noise()}
+
+ uniform sampler2D uFontTexture;
+
+ // These may be configurable in the future.
+ const float EDGE_FADE = 30;
+ const float FADE_WIDTH = 150;
+ const float TRAIL_LENGTH = 0.2;
+ const float FINAL_FADE_START_TIME = 0.8;
+ const float LETTER_TILES = 16.0;
+ const float LETTER_SIZE = ${settings.get_int('matrix-scale')};
+ const float LETTER_FLICKER_SPEED = 2.0;
+ const float RANDOMNESS = ${settings.get_double('matrix-randomness')};
+
+ // This returns a flickering grid of random letters.
+ float getText(vec2 fragCoord) {
+ vec2 pixelCoords = fragCoord * vec2(uSizeX, uSizeY);
+ vec2 uv = mod(pixelCoords.xy, LETTER_SIZE)/LETTER_SIZE;
+ vec2 block = pixelCoords/LETTER_SIZE - uv;
+
+ // Choose random letter.
+ uv += floor(rand2(floor(rand(block)*vec2(12.9898,78.233) + LETTER_FLICKER_SPEED*uTime + 42.254))*LETTER_TILES);
+
+ return texture2D(uFontTexture, uv/LETTER_TILES).r;
+ }
+
+ // This returns two values: The first are gradients for the "raindrops" which move
+ // from top to bottom. This is used for fading the letters. The second value is set
+ // to one below each drop and to zero above it. This second value is used for fading
+ // the window texture.
+ vec2 getRain(vec2 fragCoord) {
+ vec2 coords = fragCoord * vec2(uSizeX, uSizeY);
+ coords.x -= mod(coords.x, LETTER_SIZE);
+
+ float delay = fract(sin(coords.x)*78.233) * mix(0.0, 1.0, RANDOMNESS);
+ float speed = fract(cos(coords.x)*12.989) * mix(0.0, 0.3, RANDOMNESS) + 1.5;
+
+ float distToDrop = (uProgress*2-delay)*speed - fragCoord.y;
+ float rainAlpha = distToDrop >= 0 ? exp(-distToDrop/TRAIL_LENGTH) : 0;
+ float windowAlpha = 1 - clamp(uSizeY*distToDrop, 0, FADE_WIDTH) / FADE_WIDTH;
+ return vec2(rainAlpha, windowAlpha);
+ }
+
+ void main() {
+
+ // Get a cool matrix effect. See comments for those methods above.
+ vec2 rain = getRain(cogl_tex_coord_in[0].st);
+ float text = getText(cogl_tex_coord_in[0].st);
+
+ // Get the window texture and fade it according to the effect mask.
+ cogl_color_out = texture2D(uTexture, cogl_tex_coord_in[0].st) * rain.y;
+
+ // This is used to fade out the remaining trails in the end.
+ float finalFade = 1-clamp((uProgress-FINAL_FADE_START_TIME)/
+ (1-FINAL_FADE_START_TIME), 0, 1);
+ float rainAlpha = finalFade * rain.x;
+
+ // Fade at window borders.
+ vec2 pos = cogl_tex_coord_in[0].st * vec2(uSizeX, uSizeY);
+ rainAlpha *= clamp(pos.x / EDGE_FADE, 0, 1);
+ rainAlpha *= clamp(pos.y / EDGE_FADE, 0, 1);
+ rainAlpha *= clamp((uSizeX - pos.x) / EDGE_FADE, 0, 1);
+ rainAlpha *= clamp((uSizeY - pos.y) / EDGE_FADE, 0, 1);
+
+ // Add the matrix effect to the window.
+ vec3 trailColor = vec3(${trailColor.red / 255},
+ ${trailColor.green / 255},
+ ${trailColor.blue / 255});
+ vec3 tipColor = vec3(${tipColor.red / 255},
+ ${tipColor.green / 255},
+ ${tipColor.blue / 255});
+ cogl_color_out.rgb += mix(trailColor, tipColor, min(1, pow(rainAlpha+0.1, 4))) * rainAlpha * text;
+
+ // These are pretty useful for understanding how this works.
+ // cogl_color_out = vec4(vec3(text), 1);
+ // cogl_color_out = vec4(vec3(rain.x), 1);
+ // cogl_color_out = vec4(vec3(rain.y), 1);
+ }
+ `);
+ };
+
+ // This is overridden to bind the font texture for drawing. Sadly, this seems to be
+ // impossible under GNOME 3.3x as this.get_pipeline() is not available. It was called
+ // get_target() back then but this is not wrapped in GJS.
+ // https://gitlab.gnome.org/GNOME/mutter/-/blob/gnome-3-36/clutter/clutter/clutter-offscreen-effect.c#L598
+ vfunc_paint_target(node, paint_context) {
+ const pipeline = this.get_pipeline();
+ pipeline.set_layer_texture(1, this._fontTexture.get_texture());
+ this.set_uniform_value('uFontTexture', 1);
+ super.vfunc_paint_target(node, paint_context);
+ }
+});
\ No newline at end of file
diff --git a/src/extension/shaderSnippets.js b/src/extension/shaderSnippets.js
index 8e52391..93b3876 100644
--- a/src/extension/shaderSnippets.js
+++ b/src/extension/shaderSnippets.js
@@ -37,7 +37,7 @@ function standardUniforms() {
function noise() {
return `
float rand(vec2 co) {
- return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
+ return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
}
vec2 rand2(vec2 co) {
@@ -81,45 +81,3 @@ function noise() {
}
`;
}
-
-// This method requires the uniforms from standardUniforms() to be available.
-// It returns two values: The first is an alpha value which can be used for the window
-// texture. This gradually dissolves the window from top to bottom. The second can be used
-// to mask any effect, it will be most opaque where the window is currently fading and
-// gradually dissolve to zero over time.
-// hideTime: A value in [0..1]. It determines the percentage of the animation which
-// is spent for hiding the window. 1-hideTime will be spent thereafter for
-// dissolving the effect mask.
-// fadeWidth: The relative size of the window-hiding gradient in [0..1].
-// edgeFadeWidth: The pixel width of the effect fading range at the edges of the window.
-function effectMask() {
- return `
- vec2 effectMask(float hideTime, float fadeWidth, float edgeFadeWidth) {
- float burnProgress = clamp(uProgress/hideTime, 0, 1);
- float afterBurnProgress = clamp((uProgress-hideTime)/(1-hideTime), 0, 1);
-
- // Gradient from top to bottom.
- float t = cogl_tex_coord_in[0].t * (1 - fadeWidth);
-
- // Visible part of the window. Gradually dissolves towards the bottom.
- float windowMask = 1 - clamp((burnProgress - t) / fadeWidth, 0, 1);
-
- // Gradient from top burning window.
- float effectMask = clamp(t*(1-windowMask)/burnProgress, 0, 1);
-
- // Fade-out when the window burned down.
- if (uProgress > hideTime) {
- effectMask *= mix(1, 1-t, afterBurnProgress) * pow(1-afterBurnProgress, 2);
- }
-
- // Fade at window borders.
- vec2 pos = cogl_tex_coord_in[0].st * vec2(uSizeX, uSizeY);
- effectMask *= clamp(pos.x / edgeFadeWidth, 0, 1);
- effectMask *= clamp(pos.y / edgeFadeWidth, 0, 1);
- effectMask *= clamp((uSizeX - pos.x) / edgeFadeWidth, 0, 1);
- effectMask *= clamp((uSizeY - pos.y) / edgeFadeWidth, 0, 1);
-
- return vec2(windowMask, effectMask);
- }
- `;
-}
\ No newline at end of file