diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index 35029ce..03d880e 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -92,6 +92,7 @@ Please study this code carefully, all of it is explained with inline comments. // float uProgress: A value which transitions from 0 to 1 during the entire animation. // float uTime: A steadily increasing value in seconds. // vec2 uSize: The size of uTexture in pixels. +// float uPadding: The empty area around the actual window (e.g. where the shadow is drawn). #include "common/uniforms.glsl" // The width of the fading effect is loaded from the settings. diff --git a/resources/shaders/common/edgeMask.glsl b/resources/shaders/common/edgeMask.glsl index 8ad5f08..d14e981 100644 --- a/resources/shaders/common/edgeMask.glsl +++ b/resources/shaders/common/edgeMask.glsl @@ -11,11 +11,22 @@ float getEdgeMask(vec2 uv, vec2 maxUV, float fadeWidth) { return mask; } -float getAbsoluteEdgeMask(float fadePixels) { - vec2 uv = cogl_tex_coord_in[0].st * uSize; - return getEdgeMask(uv, uSize, fadePixels); +// Returns an edge mask which fades to zero at the boundaries of the actor. The width of +// the fade zone is given in pixels. This uses the standard uniforms uSize and uPadding. +// This means that the fading zone is not actually at the actors boundaries but at the +// position of the window border in the texture. +// The offset paramter controls whether the fading is placed inside the window borders +// (offset = 0), ontop the window borders (offset = 0.5) or outside the window borders +// (offset = 1). +float getAbsoluteEdgeMask(float fadePixels, float offset) { + float padding = max(0, uPadding - fadePixels * offset); + vec2 uv = cogl_tex_coord_in[0].st * uSize - padding; + return getEdgeMask(uv, uSize - 2.0 * padding, fadePixels); } +// Returns an edge mask which fades to zero at the boundaries of the actor. The width of +// the fade zone is given relative to the actor size. This neither uses uSize and +// uPadding. float getRelativeEdgeMask(float fadeAmount) { vec2 uv = cogl_tex_coord_in[0].st; return getEdgeMask(uv, vec2(1.0), fadeAmount); diff --git a/resources/shaders/common/uniforms.glsl b/resources/shaders/common/uniforms.glsl index a7db848..ab7589a 100644 --- a/resources/shaders/common/uniforms.glsl +++ b/resources/shaders/common/uniforms.glsl @@ -4,8 +4,10 @@ // uProgress: A value which transitions from 0 to 1 during the entire animation. // uTime: A steadily increasing value in seconds. // uSize: The size of uTexture in pixels. +// uPadding: The empty area around the actual window (e.g. where the shadow is drawn). uniform bool uForOpening; uniform sampler2D uTexture; uniform float uProgress; uniform float uTime; -uniform vec2 uSize; \ No newline at end of file +uniform vec2 uSize; +uniform float uPadding; \ No newline at end of file diff --git a/resources/shaders/energize-a.glsl b/resources/shaders/energize-a.glsl index 7b5d167..054058d 100644 --- a/resources/shaders/energize-a.glsl +++ b/resources/shaders/energize-a.glsl @@ -30,7 +30,7 @@ vec2 getMasks(float progress) { atomMask *= smoothstep(1.0, 0.0, fadeOutProgress); // Fade-out the masks at the window edges. - float edgeFade = getAbsoluteEdgeMask(EDGE_FADE_WIDTH); + float edgeFade = getAbsoluteEdgeMask(EDGE_FADE_WIDTH, 0.5); atomMask *= edgeFade; float heartMask = getRelativeEdgeMask(0.5); diff --git a/resources/shaders/energize-b.glsl b/resources/shaders/energize-b.glsl index 34a8b35..7283fd7 100644 --- a/resources/shaders/energize-b.glsl +++ b/resources/shaders/energize-b.glsl @@ -47,7 +47,7 @@ vec4 getMasks(float progress) { streakMask = max(streakMask, showerMask); // Fade-out the masks at the window edges. - float edgeFade = getAbsoluteEdgeMask(EDGE_FADE); + float edgeFade = getAbsoluteEdgeMask(EDGE_FADE, 0.5); streakMask *= edgeFade; showerMask *= edgeFade; diff --git a/resources/shaders/fire.glsl b/resources/shaders/fire.glsl index 99e6704..12e395a 100644 --- a/resources/shaders/fire.glsl +++ b/resources/shaders/fire.glsl @@ -72,7 +72,7 @@ vec2 effectMask(float hideTime, float fadeWidth, float edgeFadeWidth) { } // Fade at window borders. - effectMask *= getAbsoluteEdgeMask(edgeFadeWidth); + effectMask *= getAbsoluteEdgeMask(edgeFadeWidth, 0.5); if (uForOpening) { windowMask = 1.0 - windowMask; diff --git a/resources/shaders/matrix.glsl b/resources/shaders/matrix.glsl index 490f696..8b5010c 100644 --- a/resources/shaders/matrix.glsl +++ b/resources/shaders/matrix.glsl @@ -52,7 +52,7 @@ vec2 getRain(vec2 fragCoord) { float windowAlpha = 1 - clamp(uSize.y * distToDrop, 0, FADE_WIDTH) / FADE_WIDTH; // Fade at window borders. - rainAlpha *= getAbsoluteEdgeMask(EDGE_FADE); + rainAlpha *= getAbsoluteEdgeMask(EDGE_FADE, 0.5); // Add some variation to the drop start and end position. float shorten = diff --git a/src/Shader.js b/src/Shader.js index 4d53a35..bb7ec03 100644 --- a/src/Shader.js +++ b/src/Shader.js @@ -70,10 +70,17 @@ var Shader = GObject.registerClass( this._uProgress = this.get_uniform_location('uProgress'); this._uTime = this.get_uniform_location('uTime'); this._uSize = this.get_uniform_location('uSize'); + this._uPadding = this.get_uniform_location('uPadding'); } // This is called once each time the shader is used. beginAnimation(settings, forOpening, actor) { + + // This is not necessarily symmetric, but I haven't figured out a way to + // get the actual values... + const padding = (actor.width - actor.meta_window.get_frame_rect().width) / 2; + + this.set_uniform_float(this._uPadding, 1, [padding]); this.set_uniform_float(this._uForOpening, 1, [forOpening]); this.set_uniform_float(this._uSize, 2, [actor.width, actor.height]);