diff --git a/resources/shaders/apparition-declarations.glsl b/resources/shaders/apparition-declarations.glsl deleted file mode 100644 index 4f7f156..0000000 --- a/resources/shaders/apparition-declarations.glsl +++ /dev/null @@ -1,13 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" - -uniform vec2 uSeed; -uniform float uShake; -uniform float uTwirl; -uniform float uSuction; -uniform float uRandomness; - -const float ACTOR_SCALE = 2.0; -const float PADDING = ACTOR_SCALE / 2.0 - 0.5; \ No newline at end of file diff --git a/resources/shaders/apparition.glsl b/resources/shaders/apparition.glsl index 7694155..eddce19 100644 --- a/resources/shaders/apparition.glsl +++ b/resources/shaders/apparition.glsl @@ -1,33 +1,49 @@ +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" + +uniform vec2 uSeed; +uniform float uShake; +uniform float uTwirl; +uniform float uSuction; +uniform float uRandomness; + +const float ACTOR_SCALE = 2.0; +const float PADDING = ACTOR_SCALE / 2.0 - 0.5; + // The math for the whirling is inspired by this post: // http://www.geeks3d.com/20110428/shader-library-swirl-post-processing-filter-in-glsl -// We simply inverse the progress for opening windows. -float progress = uForOpening ? 1.0 - uProgress : uProgress; +void main() { + // We simply inverse the progress for opening windows. + float progress = uForOpening ? 1.0 - uProgress : uProgress; -// Choose a random suction center. -vec2 center = uSeed * uRandomness + 0.5 * (1.0 - uRandomness); -vec2 coords = cogl_tex_coord_in[0].st * ACTOR_SCALE - PADDING - center; + // Choose a random suction center. + vec2 center = uSeed * uRandomness + 0.5 * (1.0 - uRandomness); + vec2 coords = cogl_tex_coord_in[0].st * ACTOR_SCALE - PADDING - center; -// Add some shaking. -coords.x += - progress * 0.05 * uShake * sin((progress + uSeed.x) * (1.0 + uSeed.x) * uShake); -coords.y += - progress * 0.05 * uShake * cos((progress + uSeed.y) * (1.0 + uSeed.y) * uShake); + // Add some shaking. + coords.x += + progress * 0.05 * uShake * sin((progress + uSeed.x) * (1.0 + uSeed.x) * uShake); + coords.y += + progress * 0.05 * uShake * cos((progress + uSeed.y) * (1.0 + uSeed.y) * uShake); -// "Suck" the texture into the center. -float dist = length(coords) / sqrt(2); -coords += progress * coords / dist * 0.5 * uSuction; + // "Suck" the texture into the center. + float dist = length(coords) / sqrt(2); + coords += progress * coords / dist * 0.5 * uSuction; -// Apply some whirling. -float angle = pow(1.0 - dist, 2.0) * uTwirl * progress; -float s = sin(angle); -float c = cos(angle); -coords = vec2(dot(coords, vec2(c, -s)), dot(coords, vec2(s, c))); + // Apply some whirling. + float angle = pow(1.0 - dist, 2.0) * uTwirl * progress; + float s = sin(angle); + float c = cos(angle); + coords = vec2(dot(coords, vec2(c, -s)), dot(coords, vec2(s, c))); -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -cogl_color_out = texture2D(uTexture, coords + center); -if (cogl_color_out.a > 0) { - cogl_color_out.rgb /= cogl_color_out.a; -} + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + cogl_color_out = texture2D(uTexture, coords + center); + if (cogl_color_out.a > 0) { + cogl_color_out.rgb /= cogl_color_out.a; + } -// Fade out the window texture. -cogl_color_out.a *= 1.0 - progress; \ No newline at end of file + // Fade out the window texture. + cogl_color_out.a *= 1.0 - progress; +} \ No newline at end of file diff --git a/resources/shaders/broken-glass-declarations.glsl b/resources/shaders/broken-glass-declarations.glsl deleted file mode 100644 index 3c0836a..0000000 --- a/resources/shaders/broken-glass-declarations.glsl +++ /dev/null @@ -1,15 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" - -uniform sampler2D uShardTexture; -uniform vec2 uSeed; -uniform vec2 uEpicenter; -uniform float uShardScale; -uniform float uBlowForce; -uniform float uGravity; - -const float SHARD_LAYERS = 5; -const float ACTOR_SCALE = 2.0; -const float PADDING = ACTOR_SCALE / 2.0 - 0.5; \ No newline at end of file diff --git a/resources/shaders/broken-glass.glsl b/resources/shaders/broken-glass.glsl index dccffa1..306d5ac 100644 --- a/resources/shaders/broken-glass.glsl +++ b/resources/shaders/broken-glass.glsl @@ -1,49 +1,67 @@ -cogl_color_out = vec4(0, 0, 0, 0); +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" -float progress = uForOpening ? 1.0 - uProgress : uProgress; +uniform sampler2D uShardTexture; +uniform vec2 uSeed; +uniform vec2 uEpicenter; +uniform float uShardScale; +uniform float uBlowForce; +uniform float uGravity; -// Draw the individual shard layers. -for (float i = 0; i < SHARD_LAYERS; ++i) { +const float SHARD_LAYERS = 5; +const float ACTOR_SCALE = 2.0; +const float PADDING = ACTOR_SCALE / 2.0 - 0.5; - // To enable drawing shards outside of the window bounds, the actor was scaled - // by ACTOR_SCALE. Here we scale and move the texture coordinates so that the - // window gets drawn at the correct position again. - vec2 coords = cogl_tex_coord_in[0].st * ACTOR_SCALE - PADDING; +void main() { + cogl_color_out = vec4(0, 0, 0, 0); - // Scale and rotate around our epicenter. - coords -= uEpicenter; + float progress = uForOpening ? 1.0 - uProgress : uProgress; - // Scale each layer a bit differently. - coords /= mix(1.0, 1.0 + uBlowForce * (i + 2) / SHARD_LAYERS, progress); + // Draw the individual shard layers. + for (float i = 0; i < SHARD_LAYERS; ++i) { - // Rotate each layer a bit differently. - float rotation = (mod(i, 2.0) - 0.5) * 0.2 * progress; - coords = vec2(coords.x * cos(rotation) - coords.y * sin(rotation), - coords.x * sin(rotation) + coords.y * cos(rotation)); + // To enable drawing shards outside of the window bounds, the actor was scaled + // by ACTOR_SCALE. Here we scale and move the texture coordinates so that the + // window gets drawn at the correct position again. + vec2 coords = cogl_tex_coord_in[0].st * ACTOR_SCALE - PADDING; - // Move down each layer a bit. - float gravity = - (uForOpening ? -1.0 : 1.0) * uGravity * 0.1 * (i + 1) * progress * progress; - coords += vec2(0, gravity); + // Scale and rotate around our epicenter. + coords -= uEpicenter; - // Restore correct position. - coords += uEpicenter; + // Scale each layer a bit differently. + coords /= mix(1.0, 1.0 + uBlowForce * (i + 2) / SHARD_LAYERS, progress); - // Retrieve information from the shard texture for our layer. - vec2 shardCoords = (coords + uSeed) * uSize / uShardScale / 500.0; - vec2 shardMap = texture2D(uShardTexture, shardCoords).rg; + // Rotate each layer a bit differently. + float rotation = (mod(i, 2.0) - 0.5) * 0.2 * progress; + coords = vec2(coords.x * cos(rotation) - coords.y * sin(rotation), + coords.x * sin(rotation) + coords.y * cos(rotation)); - // The green channel contains a random value in [0..1] for each shard. We - // discretize this into SHARD_LAYERS bins and check if our layer falls into - // the bin of the current shard. - float shardGroup = floor(shardMap.g * SHARD_LAYERS * 0.999); + // Move down each layer a bit. + float gravity = + (uForOpening ? -1.0 : 1.0) * uGravity * 0.1 * (i + 1) * progress * progress; + coords += vec2(0, gravity); - if (shardGroup == i && (shardMap.x - pow(progress + 0.1, 2)) > 0) { - cogl_color_out = texture2D(uTexture, coords); + // Restore correct position. + coords += uEpicenter; + + // Retrieve information from the shard texture for our layer. + vec2 shardCoords = (coords + uSeed) * uSize / uShardScale / 500.0; + vec2 shardMap = texture2D(uShardTexture, shardCoords).rg; + + // The green channel contains a random value in [0..1] for each shard. We + // discretize this into SHARD_LAYERS bins and check if our layer falls into + // the bin of the current shard. + float shardGroup = floor(shardMap.g * SHARD_LAYERS * 0.999); + + if (shardGroup == i && (shardMap.x - pow(progress + 0.1, 2)) > 0) { + cogl_color_out = texture2D(uTexture, coords); + } } -} -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -if (cogl_color_out.a > 0) { - cogl_color_out.rgb /= cogl_color_out.a; + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (cogl_color_out.a > 0) { + cogl_color_out.rgb /= cogl_color_out.a; + } } \ No newline at end of file diff --git a/resources/shaders/energize-a-declarations.glsl b/resources/shaders/energize-a-declarations.glsl deleted file mode 100644 index 376fbd1..0000000 --- a/resources/shaders/energize-a-declarations.glsl +++ /dev/null @@ -1,50 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/noise.glsl" -#include "common/edgeMask.glsl" -#include "common/easing.glsl" - -uniform vec3 uColor; -uniform float uScale; - -const float FADE_IN_TIME = 0.3; -const float FADE_OUT_TIME = 0.6; -const float HEART_FADE_TIME = 0.3; -const float EDGE_FADE_WIDTH = 50; - -// This method returns two values: -// result.x: A mask for the particles. -// result.y: The opacity of the fading window. -vec2 getMasks(float progress) { - float fadeInProgress = clamp(progress / FADE_IN_TIME, 0, 1); - float fadeOutProgress = clamp((progress - FADE_IN_TIME) / FADE_OUT_TIME, 0, 1); - float heartProgress = - clamp((progress - (1.0 - HEART_FADE_TIME)) / HEART_FADE_TIME, 0, 1); - - // Compute mask for the "atom" particles. - float dist = length(cogl_tex_coord_in[0].st - 0.5) * 4.0; - float atomMask = smoothstep(0.0, 1.0, (fadeInProgress * 2.0 - dist + 1.0)); - atomMask *= fadeInProgress; - atomMask *= smoothstep(1.0, 0.0, fadeOutProgress); - - // Fade-out the masks at the window edges. - float edgeFade = getAbsoluteEdgeMask(EDGE_FADE_WIDTH); - atomMask *= edgeFade; - - float heartMask = getRelativeEdgeMask(0.5); - heartMask = 3.0 * pow(heartMask, 5); - heartMask *= fadeOutProgress; - heartMask *= 1.0 - heartProgress; - atomMask = clamp(heartMask + atomMask, 0, 1); - - // Compute fading window opacity. - float windowMask = pow(1.0 - fadeOutProgress, 2.0); - - if (uForOpening) { - windowMask = 1.0 - windowMask; - } - - return vec2(atomMask, windowMask); -} \ No newline at end of file diff --git a/resources/shaders/energize-a.glsl b/resources/shaders/energize-a.glsl index f72f2d4..7b5d167 100644 --- a/resources/shaders/energize-a.glsl +++ b/resources/shaders/energize-a.glsl @@ -1,37 +1,90 @@ -float progress = easeOutQuad(uProgress); +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/noise.glsl" +#include "common/edgeMask.glsl" +#include "common/easing.glsl" -vec2 masks = getMasks(progress); -vec4 windowColor = texture2D(uTexture, cogl_tex_coord_in[0].st); +uniform vec3 uColor; +uniform float uScale; -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -if (windowColor.a > 0) { - windowColor.rgb /= windowColor.a; +const float FADE_IN_TIME = 0.3; +const float FADE_OUT_TIME = 0.6; +const float HEART_FADE_TIME = 0.3; +const float EDGE_FADE_WIDTH = 50; + +// This method returns two values: +// result.x: A mask for the particles. +// result.y: The opacity of the fading window. +vec2 getMasks(float progress) { + float fadeInProgress = clamp(progress / FADE_IN_TIME, 0, 1); + float fadeOutProgress = clamp((progress - FADE_IN_TIME) / FADE_OUT_TIME, 0, 1); + float heartProgress = + clamp((progress - (1.0 - HEART_FADE_TIME)) / HEART_FADE_TIME, 0, 1); + + // Compute mask for the "atom" particles. + float dist = length(cogl_tex_coord_in[0].st - 0.5) * 4.0; + float atomMask = smoothstep(0.0, 1.0, (fadeInProgress * 2.0 - dist + 1.0)); + atomMask *= fadeInProgress; + atomMask *= smoothstep(1.0, 0.0, fadeOutProgress); + + // Fade-out the masks at the window edges. + float edgeFade = getAbsoluteEdgeMask(EDGE_FADE_WIDTH); + atomMask *= edgeFade; + + float heartMask = getRelativeEdgeMask(0.5); + heartMask = 3.0 * pow(heartMask, 5); + heartMask *= fadeOutProgress; + heartMask *= 1.0 - heartProgress; + atomMask = clamp(heartMask + atomMask, 0, 1); + + // Compute fading window opacity. + float windowMask = pow(1.0 - fadeOutProgress, 2.0); + + if (uForOpening) { + windowMask = 1.0 - windowMask; + } + + return vec2(atomMask, windowMask); } -// Dissolve window to effect color / transparency. -cogl_color_out.rgb = mix(uColor, windowColor.rgb, 0.2 * masks.y + 0.8); -cogl_color_out.a = windowColor.a * masks.y; +void main() { + float progress = easeOutQuad(uProgress); -vec2 scaledUV = (cogl_tex_coord_in[0].st - 0.5) * (1.0 + 0.1 * progress); -scaledUV /= uScale; + vec2 masks = getMasks(progress); + vec4 windowColor = texture2D(uTexture, cogl_tex_coord_in[0].st); -// Add molecule particles. -vec2 uv = scaledUV + vec2(0, 0.1 * uTime); -uv *= 0.010598 * vec2(0.5 * uSize.x, uSize.y); -float particles = 0.2 * pow((simplex3D(vec3(uv, 0.0 * uTime))), 3.0); + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (windowColor.a > 0) { + windowColor.rgb /= windowColor.a; + } -// Add more molecule particles. -for (int i = 1; i <= 3; ++i) { - vec2 uv = scaledUV * 0.12154 / pow(1.5, i) * uSize; - float atoms = simplex3D(vec3(uv, 2.0 * uTime / i)); - particles += 0.5 * pow(0.2 * (1.0 / (1.0 - atoms) - 1.0), 2); -} + // Dissolve window to effect color / transparency. + cogl_color_out.rgb = mix(uColor, windowColor.rgb, 0.2 * masks.y + 0.8); + cogl_color_out.a = windowColor.a * masks.y; -cogl_color_out.rgb += uColor * particles * masks.x; -cogl_color_out.a += particles * masks.x; + vec2 scaledUV = (cogl_tex_coord_in[0].st - 0.5) * (1.0 + 0.1 * progress); + scaledUV /= uScale; -// These are pretty useful for understanding how this works. -// cogl_color_out = vec4(masks, 0.0, 1.0); -// cogl_color_out = vec4(vec3(masks.x), 1.0); -// cogl_color_out = vec4(vec3(masks.y), 1.0); -// cogl_color_out = vec4(vec3(particles), 1.0); \ No newline at end of file + // Add molecule particles. + vec2 uv = scaledUV + vec2(0, 0.1 * uTime); + uv *= 0.010598 * vec2(0.5 * uSize.x, uSize.y); + float particles = 0.2 * pow((simplex3D(vec3(uv, 0.0 * uTime))), 3.0); + + // Add more molecule particles. + for (int i = 1; i <= 3; ++i) { + vec2 uv = scaledUV * 0.12154 / pow(1.5, i) * uSize; + float atoms = simplex3D(vec3(uv, 2.0 * uTime / i)); + particles += 0.5 * pow(0.2 * (1.0 / (1.0 - atoms) - 1.0), 2); + } + + cogl_color_out.rgb += uColor * particles * masks.x; + cogl_color_out.a += particles * masks.x; + + // These are pretty useful for understanding how this works. + // cogl_color_out = vec4(masks, 0.0, 1.0); + // cogl_color_out = vec4(vec3(masks.x), 1.0); + // cogl_color_out = vec4(vec3(masks.y), 1.0); + // cogl_color_out = vec4(vec3(particles), 1.0); +} \ No newline at end of file diff --git a/resources/shaders/energize-b-declarations.glsl b/resources/shaders/energize-b-declarations.glsl deleted file mode 100644 index bf10daa..0000000 --- a/resources/shaders/energize-b-declarations.glsl +++ /dev/null @@ -1,67 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/noise.glsl" -#include "common/edgeMask.glsl" -#include "common/easing.glsl" - -uniform vec3 uColor; -uniform float uScale; - -const float SHOWER_TIME = 0.3; -const float SHOWER_WIDTH = 0.3; -const float STREAK_TIME = 0.6; -const float EDGE_FADE = 50; - -// This method returns four values: -// result.x: A mask for the particles which lead the shower. -// result.y: A mask for the streaks which follow the shower particles. -// result.z: A mask for the final "atom" particles. -// result.w: The opacity of the fading window. -vec4 getMasks(float progress) { - float showerProgress = progress / SHOWER_TIME; - float streakProgress = clamp((progress - SHOWER_TIME) / STREAK_TIME, 0, 1); - float fadeProgress = clamp((progress - SHOWER_TIME) / (1.0 - SHOWER_TIME), 0, 1); - - // Gradient from top to bottom. - float t = cogl_tex_coord_in[0].t; - - // A smooth gradient which moves to the bottom within the showerProgress. - float showerMask = - smoothstep(1, 0, abs(showerProgress - t - SHOWER_WIDTH) / SHOWER_WIDTH); - - // This is 1 above the streak mask. - float streakMask = (showerProgress - t - SHOWER_WIDTH) > 0 ? 1 : 0; - - // Compute mask for the "atom" particles. - float atomMask = getRelativeEdgeMask(0.2); - atomMask = max(0, atomMask - showerMask); - atomMask *= streakMask; - atomMask *= sqrt(1 - fadeProgress * fadeProgress); - - // Make some particles visible in the streaks. - showerMask += 0.05 * streakMask; - - // Add shower mask to streak mask. - streakMask = max(streakMask, showerMask); - - // Fade-out the masks at the window edges. - float edgeFade = getAbsoluteEdgeMask(EDGE_FADE); - streakMask *= edgeFade; - showerMask *= edgeFade; - - // Fade-out the masks from top to bottom. - float fade = smoothstep(0.0, 1.0, 1.0 + t - 2.0 * streakProgress); - streakMask *= fade; - showerMask *= fade; - - // Compute fading window opacity. - float windowMask = pow(1.0 - fadeProgress, 2.0); - - if (uForOpening) { - windowMask = 1.0 - windowMask; - } - - return vec4(showerMask, streakMask, atomMask, windowMask); -} \ No newline at end of file diff --git a/resources/shaders/energize-b.glsl b/resources/shaders/energize-b.glsl index e7ecd83..34a8b35 100644 --- a/resources/shaders/energize-b.glsl +++ b/resources/shaders/energize-b.glsl @@ -1,44 +1,114 @@ -float progress = easeOutQuad(uProgress); +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/noise.glsl" +#include "common/edgeMask.glsl" +#include "common/easing.glsl" -vec4 masks = getMasks(progress); -vec4 windowColor = texture2D(uTexture, cogl_tex_coord_in[0].st); +uniform vec3 uColor; +uniform float uScale; -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -if (windowColor.a > 0) { - windowColor.rgb /= windowColor.a; +const float SHOWER_TIME = 0.3; +const float SHOWER_WIDTH = 0.3; +const float STREAK_TIME = 0.6; +const float EDGE_FADE = 50; + +// This method returns four values: +// result.x: A mask for the particles which lead the shower. +// result.y: A mask for the streaks which follow the shower particles. +// result.z: A mask for the final "atom" particles. +// result.w: The opacity of the fading window. +vec4 getMasks(float progress) { + float showerProgress = progress / SHOWER_TIME; + float streakProgress = clamp((progress - SHOWER_TIME) / STREAK_TIME, 0, 1); + float fadeProgress = clamp((progress - SHOWER_TIME) / (1.0 - SHOWER_TIME), 0, 1); + + // Gradient from top to bottom. + float t = cogl_tex_coord_in[0].t; + + // A smooth gradient which moves to the bottom within the showerProgress. + float showerMask = + smoothstep(1, 0, abs(showerProgress - t - SHOWER_WIDTH) / SHOWER_WIDTH); + + // This is 1 above the streak mask. + float streakMask = (showerProgress - t - SHOWER_WIDTH) > 0 ? 1 : 0; + + // Compute mask for the "atom" particles. + float atomMask = getRelativeEdgeMask(0.2); + atomMask = max(0, atomMask - showerMask); + atomMask *= streakMask; + atomMask *= sqrt(1 - fadeProgress * fadeProgress); + + // Make some particles visible in the streaks. + showerMask += 0.05 * streakMask; + + // Add shower mask to streak mask. + streakMask = max(streakMask, showerMask); + + // Fade-out the masks at the window edges. + float edgeFade = getAbsoluteEdgeMask(EDGE_FADE); + streakMask *= edgeFade; + showerMask *= edgeFade; + + // Fade-out the masks from top to bottom. + float fade = smoothstep(0.0, 1.0, 1.0 + t - 2.0 * streakProgress); + streakMask *= fade; + showerMask *= fade; + + // Compute fading window opacity. + float windowMask = pow(1.0 - fadeProgress, 2.0); + + if (uForOpening) { + windowMask = 1.0 - windowMask; + } + + return vec4(showerMask, streakMask, atomMask, windowMask); } -// Dissolve window to effect color / transparency. -cogl_color_out.rgb = mix(uColor, windowColor.rgb, 0.5 * masks.w + 0.5); -cogl_color_out.a = windowColor.a * masks.w; +void main() { + float progress = easeOutQuad(uProgress); -// Add leading shower particles. -vec2 showerUV = cogl_tex_coord_in[0].st + vec2(0, -0.7 * progress / SHOWER_TIME); -showerUV *= 0.02 * uSize / uScale; -float shower = pow(simplex2D(showerUV), 10.0); -cogl_color_out.rgb += uColor * shower * masks.x; -cogl_color_out.a += shower * masks.x; + vec4 masks = getMasks(progress); + vec4 windowColor = texture2D(uTexture, cogl_tex_coord_in[0].st); -// Add trailing streak lines. -vec2 streakUV = cogl_tex_coord_in[0].st + vec2(0, -progress / SHOWER_TIME); -streakUV *= vec2(0.05 * uSize.x, 0.001 * uSize.y) / uScale; -float streaks = simplex2DFractal(streakUV) * 0.5; -cogl_color_out.rgb += uColor * streaks * masks.y; -cogl_color_out.a += streaks * masks.y; + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (windowColor.a > 0) { + windowColor.rgb /= windowColor.a; + } -// Add glimmering atoms. -vec2 atomUV = cogl_tex_coord_in[0].st + vec2(0, -0.025 * progress / SHOWER_TIME); -atomUV *= 0.2 * uSize / uScale; -float atoms = pow((simplex3D(vec3(atomUV, uTime))), 5.0); -cogl_color_out.rgb += uColor * atoms * masks.z; -cogl_color_out.a += atoms * masks.z; + // Dissolve window to effect color / transparency. + cogl_color_out.rgb = mix(uColor, windowColor.rgb, 0.5 * masks.w + 0.5); + cogl_color_out.a = windowColor.a * masks.w; -// These are pretty useful for understanding how this works. -// cogl_color_out = vec4(masks.rgb, 1.0); -// cogl_color_out = vec4(vec3(masks.x), 1.0); -// cogl_color_out = vec4(vec3(masks.y), 1.0); -// cogl_color_out = vec4(vec3(masks.z), 1.0); -// cogl_color_out = vec4(vec3(masks.w), 1.0); -// cogl_color_out = vec4(vec3(shower), 1.0); -// cogl_color_out = vec4(vec3(streaks), 1.0); -// cogl_color_out = vec4(vec3(atoms), 1.0); \ No newline at end of file + // Add leading shower particles. + vec2 showerUV = cogl_tex_coord_in[0].st + vec2(0, -0.7 * progress / SHOWER_TIME); + showerUV *= 0.02 * uSize / uScale; + float shower = pow(simplex2D(showerUV), 10.0); + cogl_color_out.rgb += uColor * shower * masks.x; + cogl_color_out.a += shower * masks.x; + + // Add trailing streak lines. + vec2 streakUV = cogl_tex_coord_in[0].st + vec2(0, -progress / SHOWER_TIME); + streakUV *= vec2(0.05 * uSize.x, 0.001 * uSize.y) / uScale; + float streaks = simplex2DFractal(streakUV) * 0.5; + cogl_color_out.rgb += uColor * streaks * masks.y; + cogl_color_out.a += streaks * masks.y; + + // Add glimmering atoms. + vec2 atomUV = cogl_tex_coord_in[0].st + vec2(0, -0.025 * progress / SHOWER_TIME); + atomUV *= 0.2 * uSize / uScale; + float atoms = pow((simplex3D(vec3(atomUV, uTime))), 5.0); + cogl_color_out.rgb += uColor * atoms * masks.z; + cogl_color_out.a += atoms * masks.z; + + // These are pretty useful for understanding how this works. + // cogl_color_out = vec4(masks.rgb, 1.0); + // cogl_color_out = vec4(vec3(masks.x), 1.0); + // cogl_color_out = vec4(vec3(masks.y), 1.0); + // cogl_color_out = vec4(vec3(masks.z), 1.0); + // cogl_color_out = vec4(vec3(masks.w), 1.0); + // cogl_color_out = vec4(vec3(shower), 1.0); + // cogl_color_out = vec4(vec3(streaks), 1.0); + // cogl_color_out = vec4(vec3(atoms), 1.0); +} \ No newline at end of file diff --git a/resources/shaders/fire-declarations.glsl b/resources/shaders/fire-declarations.glsl deleted file mode 100644 index 8bdd326..0000000 --- a/resources/shaders/fire-declarations.glsl +++ /dev/null @@ -1,82 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/compositing.glsl" -#include "common/edgeMask.glsl" -#include "common/noise.glsl" -#include "common/easing.glsl" - -uniform bool u3DNoise; -uniform float uScale; -uniform float uMovementSpeed; -uniform vec4 uGradient1; -uniform vec4 uGradient2; -uniform vec4 uGradient3; -uniform vec4 uGradient4; -uniform vec4 uGradient5; - -// These may be configurable in the future. -const float EDGE_FADE = 70; -const float FADE_WIDTH = 0.1; -const float HIDE_TIME = 0.4; - -// This maps the input value from [0..1] to a color from the gradient. -vec4 getFireColor(float v) { - const float steps[5] = float[](0.0, 0.2, 0.35, 0.5, 0.8); - vec4 colors[5] = vec4[](uGradient1, uGradient2, uGradient3, uGradient4, uGradient5); - - if (v < steps[0]) { - return colors[0]; - } - - for (int i = 0; i < 4; ++i) { - if (v <= steps[i + 1]) { - return mix(colors[i], colors[i + 1], - vec4(v - steps[i]) / (steps[i + 1] - steps[i])); - } - } - - return colors[4]; -} - -// 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 progress = easeOutQuad(uProgress); - - float burnProgress = clamp(progress / hideTime, 0, 1); - float afterBurnProgress = clamp((progress - 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 (progress > hideTime) { - float fade = sqrt(1 - afterBurnProgress * afterBurnProgress); - effectMask *= mix(1, 1 - t, afterBurnProgress) * fade; - } - - // Fade at window borders. - effectMask *= getAbsoluteEdgeMask(edgeFadeWidth); - - if (uForOpening) { - windowMask = 1.0 - windowMask; - } - - return vec2(windowMask, effectMask); -} \ No newline at end of file diff --git a/resources/shaders/fire.glsl b/resources/shaders/fire.glsl index 66e7fd8..99e6704 100644 --- a/resources/shaders/fire.glsl +++ b/resources/shaders/fire.glsl @@ -1,32 +1,117 @@ -// Get a noise value which moves vertically in time. -vec2 uv = cogl_tex_coord_in[0].st * uSize / vec2(400, 600) / uScale; -uv.y += uTime * uMovementSpeed; +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/compositing.glsl" +#include "common/edgeMask.glsl" +#include "common/noise.glsl" +#include "common/easing.glsl" -float noise = u3DNoise ? simplex3DFractal(vec3(uv * 4.0, uTime* uMovementSpeed * 1.5)) - : simplex2DFractal(uv * 4.0); +uniform bool u3DNoise; +uniform float uScale; +uniform float uMovementSpeed; +uniform vec4 uGradient1; +uniform vec4 uGradient2; +uniform vec4 uGradient3; +uniform vec4 uGradient4; +uniform vec4 uGradient5; -// Modulate noise by effect mask. -vec2 effectMask = effectMask(HIDE_TIME, FADE_WIDTH, EDGE_FADE); -noise *= effectMask.y; +// These may be configurable in the future. +const float EDGE_FADE = 70; +const float FADE_WIDTH = 0.1; +const float HIDE_TIME = 0.4; -// Map noise value to color. -vec4 fire = getFireColor(noise); +// This maps the input value from [0..1] to a color from the gradient. +vec4 getFireColor(float v) { + const float steps[5] = float[](0.0, 0.2, 0.35, 0.5, 0.8); + vec4 colors[5] = vec4[](uGradient1, uGradient2, uGradient3, uGradient4, uGradient5); -// Get the window texture. -cogl_color_out = texture2D(uTexture, cogl_tex_coord_in[0].st); + if (v < steps[0]) { + return colors[0]; + } -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -if (cogl_color_out.a > 0) { - cogl_color_out.rgb /= cogl_color_out.a; + for (int i = 0; i < 4; ++i) { + if (v <= steps[i + 1]) { + return mix(colors[i], colors[i + 1], + vec4(v - steps[i]) / (steps[i + 1] - steps[i])); + } + } + + return colors[4]; } -// Fade the window according to the effect mask. -cogl_color_out.a *= effectMask.x; +// 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 progress = easeOutQuad(uProgress); -// Add the fire to the window. -cogl_color_out = alphaOver(cogl_color_out, fire); + float burnProgress = clamp(progress / hideTime, 0, 1); + float afterBurnProgress = clamp((progress - hideTime) / (1 - hideTime), 0, 1); -// These are pretty useful for understanding how this works. -// cogl_color_out = vec4(vec3(noise), 1); -// cogl_color_out = vec4(vec3(effectMask.x), 1); -// cogl_color_out = vec4(vec3(effectMask.y), 1); \ No newline at end of file + // 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 (progress > hideTime) { + float fade = sqrt(1 - afterBurnProgress * afterBurnProgress); + effectMask *= mix(1, 1 - t, afterBurnProgress) * fade; + } + + // Fade at window borders. + effectMask *= getAbsoluteEdgeMask(edgeFadeWidth); + + if (uForOpening) { + windowMask = 1.0 - windowMask; + } + + return vec2(windowMask, effectMask); +} + +void main() { + // Get a noise value which moves vertically in time. + vec2 uv = cogl_tex_coord_in[0].st * uSize / vec2(400, 600) / uScale; + uv.y += uTime * uMovementSpeed; + + float noise = u3DNoise ? simplex3DFractal(vec3(uv * 4.0, uTime * uMovementSpeed * 1.5)) + : simplex2DFractal(uv * 4.0); + + // Modulate noise by effect mask. + vec2 effectMask = effectMask(HIDE_TIME, FADE_WIDTH, EDGE_FADE); + noise *= effectMask.y; + + // Map noise value to color. + vec4 fire = getFireColor(noise); + + // Get the window texture. + cogl_color_out = texture2D(uTexture, cogl_tex_coord_in[0].st); + + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (cogl_color_out.a > 0) { + cogl_color_out.rgb /= cogl_color_out.a; + } + + // Fade the window according to the effect mask. + cogl_color_out.a *= effectMask.x; + + // Add the fire to the window. + cogl_color_out = alphaOver(cogl_color_out, fire); + + // These are pretty useful for understanding how this works. + // cogl_color_out = vec4(vec3(noise), 1); + // cogl_color_out = vec4(vec3(effectMask.x), 1); + // cogl_color_out = vec4(vec3(effectMask.y), 1); +} \ No newline at end of file diff --git a/resources/shaders/hexagon-declarations.glsl b/resources/shaders/hexagon-declarations.glsl deleted file mode 100644 index e683ee5..0000000 --- a/resources/shaders/hexagon-declarations.glsl +++ /dev/null @@ -1,54 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/noise.glsl" - -uniform bool uAdditiveBlending; -uniform vec2 uSeed; -uniform float uScale; -uniform float uLineWidth; -uniform vec4 uGlowColor; -uniform vec4 uLineColor; - -// This methods generates a procedural hexagonal pattern. It returns four values: -// result.xy: This contains cell-relative coordinates for the given point. -// [0, 0] is in the center of a cell, [0, 1] at the upper edge, -// [sqrt(4.0 / 3.0), 0] at the right tip and so on. -// result.z: This is the distance to the closest edge. This is used for shrinking -// of the tiles and the sharp overlay lines. -// result.w: This is the distance to the closest cell center. This is used for -// the glow effect. -vec4 getHexagons(vec2 p) { - - // Length of a cell's edge. - const float edgeLength = sqrt(4.0 / 3.0); - - // The hexgrid repeats after this distance. - const vec2 scale = vec2(3.0 * edgeLength, 2.0); - - // This is a repeating grid of scale-sized cells. Y-values are in the - // interval [-1...1], X-value in [-1.5*edgeLength...1.5*edgeLength]. - vec2 a = mod(p, scale) - scale * 0.5; - vec2 aAbs = abs(a); - - // This is the same as above, but offset by half scale. - vec2 b = mod(p + scale * 0.5, scale) - scale * 0.5; - vec2 bAbs = abs(b); - - // Distance to closer edge, diagonally or horizontally. - // Once for cell set A and once for cell set B. - float distA = max(aAbs.x / edgeLength + aAbs.y * 0.5, aAbs.y); - float distB = max(bAbs.x / edgeLength + bAbs.y * 0.5, bAbs.y); - - // Minimum of both is distance to closest edge. - float dist = 1.0 - min(distA, distB); - - // We use the radial distance to the center for glow. - float glow = min(dot(a, a), dot(b, b)) / 1.5; - - // Take cell-relative coordinates from the closer cell. - vec2 cellCoords = distA < distB ? a : b; - - return vec4(cellCoords, dist, glow); -} \ No newline at end of file diff --git a/resources/shaders/hexagon.glsl b/resources/shaders/hexagon.glsl index 6f0406a..79a0aa6 100644 --- a/resources/shaders/hexagon.glsl +++ b/resources/shaders/hexagon.glsl @@ -1,59 +1,116 @@ -// We simply inverse the progress for opening windows. -float progress = uForOpening ? 1.0 - uProgress : uProgress; +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/noise.glsl" -// Add some smooth noise to the progress so that not every tile behaves the -// same. -float noise = simplex2D(cogl_tex_coord_in[0].st + uSeed); -progress = clamp(mix(noise - 1.0, noise + 1.0, progress), 0.0, 1.0); +uniform bool uAdditiveBlending; +uniform vec2 uSeed; +uniform float uScale; +uniform float uLineWidth; +uniform vec4 uGlowColor; +uniform vec4 uLineColor; -// glowProgress fades in in the first half of the animation, tileProgress fades -// in in the second half. -float glowProgress = smoothstep(0, 1, clamp(progress / 0.5, 0, 1)); -float tileProgress = smoothstep(0, 1, clamp((progress - 0.5) / 0.5, 0, 1)); +// This methods generates a procedural hexagonal pattern. It returns four values: +// result.xy: This contains cell-relative coordinates for the given point. +// [0, 0] is in the center of a cell, [0, 1] at the upper edge, +// [sqrt(4.0 / 3.0), 0] at the right tip and so on. +// result.z: This is the distance to the closest edge. This is used for shrinking +// of the tiles and the sharp overlay lines. +// result.w: This is the distance to the closest cell center. This is used for +// the glow effect. +vec4 getHexagons(vec2 p) { -vec2 texScale = 0.1 * uSize / uScale; -vec4 hex = getHexagons(cogl_tex_coord_in[0].st * texScale); + // Length of a cell's edge. + const float edgeLength = sqrt(4.0 / 3.0); -if (tileProgress > hex.z) { + // The hexgrid repeats after this distance. + const vec2 scale = vec2(3.0 * edgeLength, 2.0); - // Crop outer parts of the shrinking tiles. - cogl_color_out.a = 0.0; + // This is a repeating grid of scale-sized cells. Y-values are in the + // interval [-1...1], X-value in [-1.5*edgeLength...1.5*edgeLength]. + vec2 a = mod(p, scale) - scale * 0.5; + vec2 aAbs = abs(a); -} else { + // This is the same as above, but offset by half scale. + vec2 b = mod(p + scale * 0.5, scale) - scale * 0.5; + vec2 bAbs = abs(b); - // Make the tiles shrink by offsetting the texture lookup towards the edge - // of the cell. - vec2 lookupOffset = tileProgress * hex.xy / texScale / (1.0 - tileProgress); - cogl_color_out = texture2D(uTexture, cogl_tex_coord_in[0].st + lookupOffset); + // Distance to closer edge, diagonally or horizontally. + // Once for cell set A and once for cell set B. + float distA = max(aAbs.x / edgeLength + aAbs.y * 0.5, aAbs.y); + float distB = max(bAbs.x / edgeLength + bAbs.y * 0.5, bAbs.y); - // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. - if (cogl_color_out.a > 0) { - cogl_color_out.rgb /= cogl_color_out.a; - } + // Minimum of both is distance to closest edge. + float dist = 1.0 - min(distA, distB); - vec4 glow = uGlowColor; - vec4 line = uLineColor; + // We use the radial distance to the center for glow. + float glow = min(dot(a, a), dot(b, b)) / 1.5; - // For the glow, we accumulate a few exponentially scaled versions of hex.w. - glow.a *= pow(hex.w, 20.0) * 10.0 + pow(hex.w, 10.0) * 5.0 + pow(hex.w, 2.0) * 0.5; + // Take cell-relative coordinates from the closer cell. + vec2 cellCoords = distA < distB ? a : b; - // Using step(uLineWidth, hex.z) would be simpler, but the below creates some - // fake antialiasing. - line.a *= 1.0 - smoothstep(uLineWidth * 0.02 * 0.5, uLineWidth * 0.02, hex.z); + return vec4(cellCoords, dist, glow); +} - // Fade in the glowing lines. - glow.a *= glowProgress; - line.a *= glowProgress; +void main() { + // We simply inverse the progress for opening windows. + float progress = uForOpening ? 1.0 - uProgress : uProgress; - // Do not add the hexagon lines onto transparent parts of the window. - glow *= cogl_color_out.a; - line *= cogl_color_out.a; + // Add some smooth noise to the progress so that not every tile behaves the + // same. + float noise = simplex2D(cogl_tex_coord_in[0].st + uSeed); + progress = clamp(mix(noise - 1.0, noise + 1.0, progress), 0.0, 1.0); + + // glowProgress fades in in the first half of the animation, tileProgress fades + // in in the second half. + float glowProgress = smoothstep(0, 1, clamp(progress / 0.5, 0, 1)); + float tileProgress = smoothstep(0, 1, clamp((progress - 0.5) / 0.5, 0, 1)); + + vec2 texScale = 0.1 * uSize / uScale; + vec4 hex = getHexagons(cogl_tex_coord_in[0].st * texScale); + + if (tileProgress > hex.z) { + + // Crop outer parts of the shrinking tiles. + cogl_color_out.a = 0.0; - if (uAdditiveBlending) { - cogl_color_out.rgb += glow.rgb * glow.a; - cogl_color_out.rgb += line.rgb * line.a; } else { - cogl_color_out.rgb = mix(cogl_color_out.rgb, glow.rgb, glow.a); - cogl_color_out.rgb = mix(cogl_color_out.rgb, line.rgb, line.a); + + // Make the tiles shrink by offsetting the texture lookup towards the edge + // of the cell. + vec2 lookupOffset = tileProgress * hex.xy / texScale / (1.0 - tileProgress); + cogl_color_out = texture2D(uTexture, cogl_tex_coord_in[0].st + lookupOffset); + + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (cogl_color_out.a > 0) { + cogl_color_out.rgb /= cogl_color_out.a; + } + + vec4 glow = uGlowColor; + vec4 line = uLineColor; + + // For the glow, we accumulate a few exponentially scaled versions of hex.w. + glow.a *= pow(hex.w, 20.0) * 10.0 + pow(hex.w, 10.0) * 5.0 + pow(hex.w, 2.0) * 0.5; + + // Using step(uLineWidth, hex.z) would be simpler, but the below creates some + // fake antialiasing. + line.a *= 1.0 - smoothstep(uLineWidth * 0.02 * 0.5, uLineWidth * 0.02, hex.z); + + // Fade in the glowing lines. + glow.a *= glowProgress; + line.a *= glowProgress; + + // Do not add the hexagon lines onto transparent parts of the window. + glow *= cogl_color_out.a; + line *= cogl_color_out.a; + + if (uAdditiveBlending) { + cogl_color_out.rgb += glow.rgb * glow.a; + cogl_color_out.rgb += line.rgb * line.a; + } else { + cogl_color_out.rgb = mix(cogl_color_out.rgb, glow.rgb, glow.a); + cogl_color_out.rgb = mix(cogl_color_out.rgb, line.rgb, line.a); + } } } \ No newline at end of file diff --git a/resources/shaders/matrix-declarations.glsl b/resources/shaders/matrix-declarations.glsl deleted file mode 100644 index d408bd1..0000000 --- a/resources/shaders/matrix-declarations.glsl +++ /dev/null @@ -1,68 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/noise.glsl" -#include "common/edgeMask.glsl" -#include "common/compositing.glsl" - -uniform sampler2D uFontTexture; -uniform vec3 uTrailColor; -uniform vec3 uTipColor; -uniform float uLetterSize; -uniform float uRandomness; -uniform float uOverShoot; - -// 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_FLICKER_SPEED = 2.0; - -// This returns a flickering grid of random letters. -float getText(vec2 fragCoord) { - vec2 pixelCoords = fragCoord * uSize; - vec2 uv = mod(pixelCoords.xy, uLetterSize) / uLetterSize; - vec2 block = pixelCoords / uLetterSize - uv; - - // Choose random letter. - uv += floor(hash22(floor(hash22(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) { - float column = cogl_tex_coord_in[0].x * uSize.x; - column -= mod(column, uLetterSize); - - float delay = fract(sin(column) * 78.233) * mix(0.0, 1.0, uRandomness); - float speed = fract(cos(column) * 12.989) * mix(0.0, 0.3, uRandomness) + 1.5; - - float distToDrop = (uProgress * 2 - delay) * speed - cogl_tex_coord_in[0].y; - - float rainAlpha = distToDrop >= 0 ? exp(-distToDrop / TRAIL_LENGTH) : 0; - float windowAlpha = 1 - clamp(uSize.y * distToDrop, 0, FADE_WIDTH) / FADE_WIDTH; - - // Fade at window borders. - rainAlpha *= getAbsoluteEdgeMask(EDGE_FADE); - - // Add some variation to the drop start and end position. - float shorten = - fract(sin(column + 42.0) * 33.423) * mix(0.0, uOverShoot * 0.25, uRandomness); - rainAlpha *= smoothstep(0, 1, clamp(cogl_tex_coord_in[0].y / shorten, 0, 1)); - rainAlpha *= smoothstep(0, 1, clamp((1.0 - cogl_tex_coord_in[0].y) / shorten, 0, 1)); - - if (uForOpening) { - windowAlpha = 1.0 - windowAlpha; - } - - return vec2(rainAlpha, windowAlpha); -} \ No newline at end of file diff --git a/resources/shaders/matrix.glsl b/resources/shaders/matrix.glsl index ace5ccb..490f696 100644 --- a/resources/shaders/matrix.glsl +++ b/resources/shaders/matrix.glsl @@ -1,32 +1,103 @@ -vec2 coords = cogl_tex_coord_in[0].st; -coords.y = coords.y * (uOverShoot + 1.0) - uOverShoot * 0.5; +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/noise.glsl" +#include "common/edgeMask.glsl" +#include "common/compositing.glsl" -// Get a cool matrix effect. See comments for those methods above. -vec2 rainMask = getRain(coords); -float textMask = getText(coords); +uniform sampler2D uFontTexture; +uniform vec3 uTrailColor; +uniform vec3 uTipColor; +uniform float uLetterSize; +uniform float uRandomness; +uniform float uOverShoot; -// Get the window texture. -cogl_color_out = texture2D(uTexture, coords); +// 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_FLICKER_SPEED = 2.0; -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -if (cogl_color_out.a > 0) { - cogl_color_out.rgb /= cogl_color_out.a; +// This returns a flickering grid of random letters. +float getText(vec2 fragCoord) { + vec2 pixelCoords = fragCoord * uSize; + vec2 uv = mod(pixelCoords.xy, uLetterSize) / uLetterSize; + vec2 block = pixelCoords / uLetterSize - uv; + + // Choose random letter. + uv += floor(hash22(floor(hash22(block) * vec2(12.9898, 78.233) + + LETTER_FLICKER_SPEED * uTime + 42.254)) * + LETTER_TILES); + + return texture2D(uFontTexture, uv / LETTER_TILES).r; } -// Fade the window according to the effect mask. -cogl_color_out.a *= rainMask.y; +// 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) { + float column = cogl_tex_coord_in[0].x * uSize.x; + column -= mod(column, uLetterSize); -// 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 * rainMask.x; + float delay = fract(sin(column) * 78.233) * mix(0.0, 1.0, uRandomness); + float speed = fract(cos(column) * 12.989) * mix(0.0, 0.3, uRandomness) + 1.5; -// Add the matrix effect to the window. -vec4 text = - vec4(mix(uTrailColor, uTipColor, min(1, pow(rainAlpha + 0.1, 4))), rainAlpha* textMask); -cogl_color_out = alphaOver(cogl_color_out, text); + float distToDrop = (uProgress * 2 - delay) * speed - cogl_tex_coord_in[0].y; -// These are pretty useful for understanding how this works. -// cogl_color_out = vec4(vec3(textMask), 1); -// cogl_color_out = vec4(vec3(rainMask.x), 1); -// cogl_color_out = vec4(vec3(rainMask.y), 1); \ No newline at end of file + float rainAlpha = distToDrop >= 0 ? exp(-distToDrop / TRAIL_LENGTH) : 0; + float windowAlpha = 1 - clamp(uSize.y * distToDrop, 0, FADE_WIDTH) / FADE_WIDTH; + + // Fade at window borders. + rainAlpha *= getAbsoluteEdgeMask(EDGE_FADE); + + // Add some variation to the drop start and end position. + float shorten = + fract(sin(column + 42.0) * 33.423) * mix(0.0, uOverShoot * 0.25, uRandomness); + rainAlpha *= smoothstep(0, 1, clamp(cogl_tex_coord_in[0].y / shorten, 0, 1)); + rainAlpha *= smoothstep(0, 1, clamp((1.0 - cogl_tex_coord_in[0].y) / shorten, 0, 1)); + + if (uForOpening) { + windowAlpha = 1.0 - windowAlpha; + } + + return vec2(rainAlpha, windowAlpha); +} + +void main() { + vec2 coords = cogl_tex_coord_in[0].st; + coords.y = coords.y * (uOverShoot + 1.0) - uOverShoot * 0.5; + + // Get a cool matrix effect. See comments for those methods above. + vec2 rainMask = getRain(coords); + float textMask = getText(coords); + + // Get the window texture. + cogl_color_out = texture2D(uTexture, coords); + + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (cogl_color_out.a > 0) { + cogl_color_out.rgb /= cogl_color_out.a; + } + + // Fade the window according to the effect mask. + cogl_color_out.a *= rainMask.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 * rainMask.x; + + // Add the matrix effect to the window. + vec4 text = vec4(mix(uTrailColor, uTipColor, min(1, pow(rainAlpha + 0.1, 4))), + rainAlpha * textMask); + cogl_color_out = alphaOver(cogl_color_out, text); + + // These are pretty useful for understanding how this works. + // cogl_color_out = vec4(vec3(textMask), 1); + // cogl_color_out = vec4(vec3(rainMask.x), 1); + // cogl_color_out = vec4(vec3(rainMask.y), 1); +} \ No newline at end of file diff --git a/resources/shaders/snap-declarations.glsl b/resources/shaders/snap-declarations.glsl deleted file mode 100644 index c704df5..0000000 --- a/resources/shaders/snap-declarations.glsl +++ /dev/null @@ -1,18 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/noise.glsl" -#include "common/math2D.glsl" - -uniform sampler2D uDustTexture; -uniform vec4 uDustColor; -uniform vec2 uSeed; -uniform float uDustScale; - -const float DUST_LAYERS = 4; -const float GROW_INTENSITY = 0.05; -const float SHRINK_INTENSITY = 0.05; -const float WIND_INTENSITY = 0.05; -const float ACTOR_SCALE = 1.2; -const float PADDING = ACTOR_SCALE / 2.0 - 0.5; \ No newline at end of file diff --git a/resources/shaders/snap.glsl b/resources/shaders/snap.glsl index a94f946..bf1489f 100644 --- a/resources/shaders/snap.glsl +++ b/resources/shaders/snap.glsl @@ -1,71 +1,92 @@ -// We simply inverse the progress for opening windows. -float progress = uForOpening ? uProgress : 1.0 - uProgress; +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/noise.glsl" +#include "common/math2D.glsl" -float gradient = cogl_tex_coord_in[0].t * ACTOR_SCALE - PADDING; -progress = 2.0 - gradient - 2.0 * progress; -progress = progress + 0.25 - 0.5 * simplex2D((cogl_tex_coord_in[0].st + uSeed) * 2.0); -progress = pow(max(0, progress), 2.0); +uniform sampler2D uDustTexture; +uniform vec4 uDustColor; +uniform vec2 uSeed; +uniform float uDustScale; -// This may help you to understand how this effect works. -// cogl_color_out = vec4(progress, 0, 0, 0); -// return; +const float DUST_LAYERS = 4; +const float GROW_INTENSITY = 0.05; +const float SHRINK_INTENSITY = 0.05; +const float WIND_INTENSITY = 0.05; +const float ACTOR_SCALE = 1.2; +const float PADDING = ACTOR_SCALE / 2.0 - 0.5; -cogl_color_out = vec4(0, 0, 0, 0); +void main() { + // We simply inverse the progress for opening windows. + float progress = uForOpening ? uProgress : 1.0 - uProgress; -for (float i = 0; i < DUST_LAYERS; ++i) { + float gradient = cogl_tex_coord_in[0].t * ACTOR_SCALE - PADDING; + progress = 2.0 - gradient - 2.0 * progress; + progress = progress + 0.25 - 0.5 * simplex2D((cogl_tex_coord_in[0].st + uSeed) * 2.0); + progress = pow(max(0, progress), 2.0); - // Create a random direction. - float factor = DUST_LAYERS == 1 ? 0 : i / (DUST_LAYERS - 1); - float angle = 123.123 * (uSeed.x + factor); - vec2 direction = vec2(1.0, 0.0); - direction = rotate(direction, angle); + // This may help you to understand how this effect works. + // cogl_color_out = vec4(progress, 0, 0, 0); + // return; - // Flip direction for one side of the window. - vec2 coords = cogl_tex_coord_in[0].st * ACTOR_SCALE - PADDING - 0.5; - if (getWinding(direction, coords) > 0) { - direction *= -1; - } + cogl_color_out = vec4(0, 0, 0, 0); - // Flip direction for half the layers. - if (factor > 0.5) { - direction *= -1; - } + for (float i = 0; i < DUST_LAYERS; ++i) { - // We grow the layer along the random direction, shrink it orthogonally to it - // and scale it up slightly. - float dist = distToLine(vec2(0.0), direction, coords); - vec2 grow = direction * dist * mix(0, GROW_INTENSITY, progress); - vec2 shrink = - vec2(direction.y, -direction.x) * dist * mix(0, SHRINK_INTENSITY, progress); - float scale = mix(1.0, 1.05, factor * progress); - coords = (coords + grow + shrink) / scale; + // Create a random direction. + float factor = DUST_LAYERS == 1 ? 0 : i / (DUST_LAYERS - 1); + float angle = 123.123 * (uSeed.x + factor); + vec2 direction = vec2(1.0, 0.0); + direction = rotate(direction, angle); - // Add some wind. - coords.x += WIND_INTENSITY * progress * (uForOpening ? 1.0 : -1.0); - - // Now check wether there is actually something in the current dust layer at - // the coords position. - vec2 dustCoords = (coords + uSeed) * uSize / uDustScale / 100.0; - vec2 dustMap = texture2D(uDustTexture, dustCoords).rg; - float dustGroup = floor(dustMap.g * DUST_LAYERS * 0.999); - - if (dustGroup == i) { - - // Get the window color. - vec4 windowColor = texture2D(uTexture, coords + 0.5); - - // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. - if (windowColor.a > 0) { - windowColor.rgb /= windowColor.a; + // Flip direction for one side of the window. + vec2 coords = cogl_tex_coord_in[0].st * ACTOR_SCALE - PADDING - 0.5; + if (getWinding(direction, coords) > 0) { + direction *= -1; } - // Fade the window color to uDustColor. - vec3 dustColor = mix(windowColor.rgb, uDustColor.rgb, uDustColor.a); - windowColor.rgb = mix(windowColor.rgb, dustColor, progress); + // Flip direction for half the layers. + if (factor > 0.5) { + direction *= -1; + } - // Dissolve and blend the layers. - if (dustMap.x - progress > 0) { - cogl_color_out = windowColor; + // We grow the layer along the random direction, shrink it orthogonally to it + // and scale it up slightly. + float dist = distToLine(vec2(0.0), direction, coords); + vec2 grow = direction * dist * mix(0, GROW_INTENSITY, progress); + vec2 shrink = + vec2(direction.y, -direction.x) * dist * mix(0, SHRINK_INTENSITY, progress); + float scale = mix(1.0, 1.05, factor * progress); + coords = (coords + grow + shrink) / scale; + + // Add some wind. + coords.x += WIND_INTENSITY * progress * (uForOpening ? 1.0 : -1.0); + + // Now check wether there is actually something in the current dust layer at + // the coords position. + vec2 dustCoords = (coords + uSeed) * uSize / uDustScale / 100.0; + vec2 dustMap = texture2D(uDustTexture, dustCoords).rg; + float dustGroup = floor(dustMap.g * DUST_LAYERS * 0.999); + + if (dustGroup == i) { + + // Get the window color. + vec4 windowColor = texture2D(uTexture, coords + 0.5); + + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (windowColor.a > 0) { + windowColor.rgb /= windowColor.a; + } + + // Fade the window color to uDustColor. + vec3 dustColor = mix(windowColor.rgb, uDustColor.rgb, uDustColor.a); + windowColor.rgb = mix(windowColor.rgb, dustColor, progress); + + // Dissolve and blend the layers. + if (dustMap.x - progress > 0) { + cogl_color_out = windowColor; + } } } } \ No newline at end of file diff --git a/resources/shaders/trex-declarations.glsl b/resources/shaders/trex-declarations.glsl deleted file mode 100644 index 58f046f..0000000 --- a/resources/shaders/trex-declarations.glsl +++ /dev/null @@ -1,58 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/noise.glsl" -#include "common/compositing.glsl" -#include "common/easing.glsl" - -// See assets/README.md for how this texture was created. -uniform sampler2D uClawTexture; -uniform vec4 uFlashColor; -uniform vec2 uSeed; -uniform float uClawSize; -uniform float uNumClaws; -uniform float uWarpIntensity; - -const float FLASH_INTENSITY = 0.1; -const float MAX_SPAWN_TIME = - 0.6; // Scratches will only start in the first half of the animation. -const float FF_TIME = 0.6; // Relative time for the final fade to transparency. - -// This method generates a grid of randomly rotated, slightly shifted and scaled -// UV squares. It returns the texture coords of the UV square at the given actor -// coordinates. If these do not fall into one of the UV grids, the coordinates of -// the closest UV grid will be clamped and returned. -vec2 getClawUV(vec2 texCoords, float gridScale, vec2 seed) { - - // Shift coordinates by a random offset and make sure the have a 1:1 aspect ratio. - vec2 coords = texCoords + hash22(seed); - coords *= uSize.x < uSize.y ? vec2(1.0, 1.0 * uSize.y / uSize.x) - : vec2(1.0 * uSize.x / uSize.y, 1.0); - - // Apply global scale. - coords *= gridScale; - - // Get grid cell coordinates in [0..1]. - vec2 cellUV = mod(coords, vec2(1)); - - // This is unique for each cell. - vec2 cellID = coords - cellUV + vec2(362.456); - - // Add random rotation, scale and offset to each grid cell. - float scale = mix(0.8, 1.0, hash12(cellID * seed * 134.451)); - float offsetX = mix(0.0, 1.0 - scale, hash12(cellID * seed * 54.4129)); - float offsetY = mix(0.0, 1.0 - scale, hash12(cellID * seed * 25.3089)); - float rotation = mix(0.0, 2.0 * 3.141, hash12(cellID * seed * 2.99837)); - - cellUV -= vec2(offsetX, offsetY); - cellUV /= scale; - - cellUV -= 0.5; - cellUV = vec2(cellUV.x * cos(rotation) - cellUV.y * sin(rotation), - cellUV.x * sin(rotation) + cellUV.y * cos(rotation)); - cellUV += 0.5; - - // Clamp resulting coordinates. - return clamp(cellUV, vec2(0), vec2(1)); -} \ No newline at end of file diff --git a/resources/shaders/trex.glsl b/resources/shaders/trex.glsl index 52b79dd..3916b15 100644 --- a/resources/shaders/trex.glsl +++ b/resources/shaders/trex.glsl @@ -1,55 +1,116 @@ -float progress = uForOpening ? 1.0 - easeOutQuad(uProgress) : easeOutQuad(uProgress); +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/noise.glsl" +#include "common/compositing.glsl" +#include "common/easing.glsl" -// Warp the texture coordinates to create a blow-up effect. -vec2 coords = cogl_tex_coord_in[0].st * 2.0 - 1.0; -float dist = length(coords); -coords = (coords / dist * pow(dist, 1.0 + uWarpIntensity)) * 0.5 + 0.5; -coords = mix(cogl_tex_coord_in[0].st, coords, progress); +// See assets/README.md for how this texture was created. +uniform sampler2D uClawTexture; +uniform vec4 uFlashColor; +uniform vec2 uSeed; +uniform float uClawSize; +uniform float uNumClaws; +uniform float uWarpIntensity; -// Scale down the window according to the warp. -float scale = 0.5 * uWarpIntensity * (1.0 - progress); -coords = coords * (scale + 1.0) - scale * 0.5; +const float FLASH_INTENSITY = 0.1; +const float MAX_SPAWN_TIME = + 0.6; // Scratches will only start in the first half of the animation. +const float FF_TIME = 0.6; // Relative time for the final fade to transparency. -// Accumulate several random scratches. The color in the scratch map refers to the -// relative time when the respective part will become invisible. Therefore we can -// add a value to make the scratch appear later. -float scratchMap = 1.0; -for (int i = 0; i < uNumClaws; ++i) { - vec2 uv = getClawUV(coords, 1.0 / uClawSize, uSeed * (i + 1)); - float delay = i / uNumClaws * MAX_SPAWN_TIME; - scratchMap = min(scratchMap, clamp(texture2D(uClawTexture, uv).r + delay, 0, 1)); +// This method generates a grid of randomly rotated, slightly shifted and scaled +// UV squares. It returns the texture coords of the UV square at the given actor +// coordinates. If these do not fall into one of the UV grids, the coordinates of +// the closest UV grid will be clamped and returned. +vec2 getClawUV(vec2 texCoords, float gridScale, vec2 seed) { + + // Shift coordinates by a random offset and make sure the have a 1:1 aspect ratio. + vec2 coords = texCoords + hash22(seed); + coords *= uSize.x < uSize.y ? vec2(1.0, 1.0 * uSize.y / uSize.x) + : vec2(1.0 * uSize.x / uSize.y, 1.0); + + // Apply global scale. + coords *= gridScale; + + // Get grid cell coordinates in [0..1]. + vec2 cellUV = mod(coords, vec2(1)); + + // This is unique for each cell. + vec2 cellID = coords - cellUV + vec2(362.456); + + // Add random rotation, scale and offset to each grid cell. + float scale = mix(0.8, 1.0, hash12(cellID * seed * 134.451)); + float offsetX = mix(0.0, 1.0 - scale, hash12(cellID * seed * 54.4129)); + float offsetY = mix(0.0, 1.0 - scale, hash12(cellID * seed * 25.3089)); + float rotation = mix(0.0, 2.0 * 3.141, hash12(cellID * seed * 2.99837)); + + cellUV -= vec2(offsetX, offsetY); + cellUV /= scale; + + cellUV -= 0.5; + cellUV = vec2(cellUV.x * cos(rotation) - cellUV.y * sin(rotation), + cellUV.x * sin(rotation) + cellUV.y * cos(rotation)); + cellUV += 0.5; + + // Clamp resulting coordinates. + return clamp(cellUV, vec2(0), vec2(1)); } -// Get the window texture. We shift the texture lookup by the local derivative of -// the claw texture in order to mimic some folding distortion. -vec2 offset = vec2(dFdx(scratchMap), dFdy(scratchMap)) * progress * 0.5; -cogl_color_out = texture2D(uTexture, coords + offset); +void main() { + float progress = uForOpening ? 1.0 - easeOutQuad(uProgress) : easeOutQuad(uProgress); -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -if (cogl_color_out.a > 0) { - cogl_color_out.rgb /= cogl_color_out.a; -} + // Warp the texture coordinates to create a blow-up effect. + vec2 coords = cogl_tex_coord_in[0].st * 2.0 - 1.0; + float dist = length(coords); + coords = (coords / dist * pow(dist, 1.0 + uWarpIntensity)) * 0.5 + 0.5; + coords = mix(cogl_tex_coord_in[0].st, coords, progress); -// Add colorful flashes. -float flashIntensity = 1.0 / FLASH_INTENSITY * (scratchMap - progress) + 1; -if (flashIntensity < 0 || flashIntensity >= 1) { - flashIntensity = 0; -} + // Scale down the window according to the warp. + float scale = 0.5 * uWarpIntensity * (1.0 - progress); + coords = coords * (scale + 1.0) - scale * 0.5; -// Hide flashes where there is now window. -vec4 flash = uFlashColor; -flash.a *= flashIntensity * cogl_color_out.a * (1.0 - progress); + // Accumulate several random scratches. The color in the scratch map refers to the + // relative time when the respective part will become invisible. Therefore we can + // add a value to make the scratch appear later. + float scratchMap = 1.0; + for (int i = 0; i < uNumClaws; ++i) { + vec2 uv = getClawUV(coords, 1.0 / uClawSize, uSeed * (i + 1)); + float delay = i / uNumClaws * MAX_SPAWN_TIME; + scratchMap = min(scratchMap, clamp(texture2D(uClawTexture, uv).r + delay, 0, 1)); + } -// Hide scratched out parts. -cogl_color_out.a *= (scratchMap > progress ? 1 : 0); + // Get the window texture. We shift the texture lookup by the local derivative of + // the claw texture in order to mimic some folding distortion. + vec2 offset = vec2(dFdx(scratchMap), dFdy(scratchMap)) * progress * 0.5; + cogl_color_out = texture2D(uTexture, coords + offset); -// Add flash color. -cogl_color_out = alphaOver(cogl_color_out, flash); + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (cogl_color_out.a > 0) { + cogl_color_out.rgb /= cogl_color_out.a; + } -// Fade out the remaining shards. -float fadeProgress = smoothstep(0, 1, (progress - 1.0 + FF_TIME) / FF_TIME); -cogl_color_out.a *= sqrt(1 - fadeProgress * fadeProgress); + // Add colorful flashes. + float flashIntensity = 1.0 / FLASH_INTENSITY * (scratchMap - progress) + 1; + if (flashIntensity < 0 || flashIntensity >= 1) { + flashIntensity = 0; + } -// These are pretty useful for understanding how this works. -// cogl_color_out = vec4(vec3(flashIntensity), 1); -// cogl_color_out = vec4(vec3(scratchMap), 1); \ No newline at end of file + // Hide flashes where there is now window. + vec4 flash = uFlashColor; + flash.a *= flashIntensity * cogl_color_out.a * (1.0 - progress); + + // Hide scratched out parts. + cogl_color_out.a *= (scratchMap > progress ? 1 : 0); + + // Add flash color. + cogl_color_out = alphaOver(cogl_color_out, flash); + + // Fade out the remaining shards. + float fadeProgress = smoothstep(0, 1, (progress - 1.0 + FF_TIME) / FF_TIME); + cogl_color_out.a *= sqrt(1 - fadeProgress * fadeProgress); + + // These are pretty useful for understanding how this works. + // cogl_color_out = vec4(vec3(flashIntensity), 1); + // cogl_color_out = vec4(vec3(scratchMap), 1); +} \ No newline at end of file diff --git a/resources/shaders/tv-declarations.glsl b/resources/shaders/tv-declarations.glsl deleted file mode 100644 index 828c2ed..0000000 --- a/resources/shaders/tv-declarations.glsl +++ /dev/null @@ -1,14 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/easing.glsl" - -uniform vec3 uColor; - -const float BLUR_WIDTH = 0.01; // Width of the gradients. -const float TB_TIME = 0.7; // Relative time for the top/bottom animation. -const float LR_TIME = 0.4; // Relative time for the left/right animation. -const float LR_DELAY = 0.6; // Delay after which the left/right animation starts. -const float FF_TIME = 0.1; // Relative time for the final fade to transparency. -const float SCALING = 0.5; // Additional vertical scaling of the window. \ No newline at end of file diff --git a/resources/shaders/tv.glsl b/resources/shaders/tv.glsl index 387c2dd..0201350 100644 --- a/resources/shaders/tv.glsl +++ b/resources/shaders/tv.glsl @@ -1,47 +1,64 @@ -float progress = uForOpening ? 1.0 - easeOutQuad(uProgress) : easeOutQuad(uProgress); +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/easing.glsl" -// Scale down the window vertically. -float scale = 1.0 / mix(1.0, SCALING, progress) - 1.0; -vec2 coords = cogl_tex_coord_in[0].st; -coords.y = coords.y * (scale + 1.0) - scale * 0.5; +uniform vec3 uColor; -// All of these are in [0..1] during the different stages of the animation. -// tb refers to the top-bottom animation. -// lr refers to the left-right animation. -// ff refers to the final fade animation. -float tbProgress = smoothstep(0, 1, clamp(progress / TB_TIME, 0, 1)); -float lrProgress = smoothstep(0, 1, clamp((progress - LR_DELAY) / LR_TIME, 0, 1)); -float ffProgress = smoothstep(0, 1, clamp((progress - 1.0 + FF_TIME) / FF_TIME, 0, 1)); +const float BLUR_WIDTH = 0.01; // Width of the gradients. +const float TB_TIME = 0.7; // Relative time for the top/bottom animation. +const float LR_TIME = 0.4; // Relative time for the left/right animation. +const float LR_DELAY = 0.6; // Delay after which the left/right animation starts. +const float FF_TIME = 0.1; // Relative time for the final fade to transparency. +const float SCALING = 0.5; // Additional vertical scaling of the window. -// This is a top-center-bottom gradient in [0..1..0] -float tb = coords.y * 2; -tb = tb < 1 ? tb : 2 - tb; +void main() { + float progress = uForOpening ? 1.0 - easeOutQuad(uProgress) : easeOutQuad(uProgress); -// This is a left-center-right gradient in [0..1..0] -float lr = coords.x * 2; -lr = lr < 1 ? lr : 2 - lr; + // Scale down the window vertically. + float scale = 1.0 / mix(1.0, SCALING, progress) - 1.0; + vec2 coords = cogl_tex_coord_in[0].st; + coords.y = coords.y * (scale + 1.0) - scale * 0.5; -// Combine the progress values with the gradients to create the alpha masks. -float tbMask = 1 - smoothstep(0, 1, clamp((tbProgress - tb) / BLUR_WIDTH, 0, 1)); -float lrMask = 1 - smoothstep(0, 1, clamp((lrProgress - lr) / BLUR_WIDTH, 0, 1)); -float ffMask = 1 - smoothstep(0, 1, ffProgress); + // All of these are in [0..1] during the different stages of the animation. + // tb refers to the top-bottom animation. + // lr refers to the left-right animation. + // ff refers to the final fade animation. + float tbProgress = smoothstep(0, 1, clamp(progress / TB_TIME, 0, 1)); + float lrProgress = smoothstep(0, 1, clamp((progress - LR_DELAY) / LR_TIME, 0, 1)); + float ffProgress = smoothstep(0, 1, clamp((progress - 1.0 + FF_TIME) / FF_TIME, 0, 1)); -// Assemble the final alpha value. -float mask = tbMask * lrMask * ffMask; + // This is a top-center-bottom gradient in [0..1..0] + float tb = coords.y * 2; + tb = tb < 1 ? tb : 2 - tb; -cogl_color_out = texture2D(uTexture, coords); + // This is a left-center-right gradient in [0..1..0] + float lr = coords.x * 2; + lr = lr < 1 ? lr : 2 - lr; -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -if (cogl_color_out.a > 0) { - cogl_color_out.rgb /= cogl_color_out.a; -} + // Combine the progress values with the gradients to create the alpha masks. + float tbMask = 1 - smoothstep(0, 1, clamp((tbProgress - tb) / BLUR_WIDTH, 0, 1)); + float lrMask = 1 - smoothstep(0, 1, clamp((lrProgress - lr) / BLUR_WIDTH, 0, 1)); + float ffMask = 1 - smoothstep(0, 1, ffProgress); -cogl_color_out.rgb = - mix(cogl_color_out.rgb, uColor* cogl_color_out.a, smoothstep(0, 1, progress)); -cogl_color_out.a *= mask; + // Assemble the final alpha value. + float mask = tbMask * lrMask * ffMask; -// These are pretty useful for understanding how this works. -// cogl_color_out = vec4(vec3(tbMask), 1); -// cogl_color_out = vec4(vec3(lrMask), 1); -// cogl_color_out = vec4(vec3(ffMask), 1); -// cogl_color_out = vec4(vec3(mask), 1); \ No newline at end of file + cogl_color_out = texture2D(uTexture, coords); + + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (cogl_color_out.a > 0) { + cogl_color_out.rgb /= cogl_color_out.a; + } + + cogl_color_out.rgb = + mix(cogl_color_out.rgb, uColor * cogl_color_out.a, smoothstep(0, 1, progress)); + cogl_color_out.a *= mask; + + // These are pretty useful for understanding how this works. + // cogl_color_out = vec4(vec3(tbMask), 1); + // cogl_color_out = vec4(vec3(lrMask), 1); + // cogl_color_out = vec4(vec3(ffMask), 1); + // cogl_color_out = vec4(vec3(mask), 1); +} \ No newline at end of file diff --git a/resources/shaders/wisps-declarations.glsl b/resources/shaders/wisps-declarations.glsl deleted file mode 100644 index 739fb4e..0000000 --- a/resources/shaders/wisps-declarations.glsl +++ /dev/null @@ -1,58 +0,0 @@ -// Inject some common shader snippets. It is only possible to include glsl files from the -// "common" directory. Also, the files in the "common" directory are not allowed to -// include any further files. -#include "common/uniforms.glsl" -#include "common/noise.glsl" -#include "common/edgeMask.glsl" -#include "common/compositing.glsl" -#include "common/easing.glsl" - -uniform vec2 uSeed; -uniform vec3 uColor; -uniform float uScale; - -const float WISPS_RADIUS = 20.0; -const float WISPS_SPEED = 10.0; -const float WISPS_SPACING = 40 + WISPS_RADIUS; -const int WISPS_LAYERS = 8; -const float WISPS_IN_TIME = 0.5; -const float WINDOW_OUT_TIME = 1.0; -const float SCALING = 0.9; - -// Returns a grid of randomly moving points. Each grid cell contains one point which -// moves on an ellipse. -float getWisps(vec2 texCoords, float gridSize, vec2 seed) { - - // Shift coordinates by a random offset and make sure the have a 1:1 aspect ratio. - vec2 coords = (texCoords + hash22(seed)) * uSize; - - // Apply global scale. - coords /= gridSize; - - // Get grid cell coordinates in [0..1]. - vec2 cellUV = mod(coords, vec2(1)); - - // This is unique for each cell. - vec2 cellID = coords - cellUV + vec2(362.456); - - // Add random rotation, scale and offset to each grid cell. - float speed = mix(10.0, 15.0, hash12(cellID * seed * 134.451)) / gridSize * WISPS_SPEED; - float rotation = mix(0.0, 6.283, hash12(cellID * seed * 54.4129)); - float radius = mix(0.5, 1.0, hash12(cellID * seed * 19.1249)) * WISPS_RADIUS; - float roundness = mix(-1.0, 1.0, hash12(cellID * seed * 7.51949)); - - vec2 offset = vec2(sin(speed * (uTime + 1)) * roundness, cos(speed * (uTime + 1))); - offset *= 0.5 - 0.5 * radius / gridSize; - offset = vec2(offset.x * cos(rotation) - offset.y * sin(rotation), - offset.x * sin(rotation) + offset.y * cos(rotation)); - - cellUV += offset; - - // Use distance to center of shifted / rotated UV coordinates to draw a glaring point. - float dist = length(cellUV - 0.5) * gridSize / radius; - if (dist < 1.0) { - return min(5, 0.01 / pow(dist, 2.0)); - } - - return 0.0; -} \ No newline at end of file diff --git a/resources/shaders/wisps.glsl b/resources/shaders/wisps.glsl index 39092eb..008ca73 100644 --- a/resources/shaders/wisps.glsl +++ b/resources/shaders/wisps.glsl @@ -1,46 +1,107 @@ -float progress = uForOpening ? 1.0 - easeOutQuad(uProgress) : easeOutQuad(uProgress); +// Inject some common shader snippets. It is only possible to include glsl files from the +// "common" directory. Also, the files in the "common" directory are not allowed to +// include any further files. +#include "common/uniforms.glsl" +#include "common/noise.glsl" +#include "common/edgeMask.glsl" +#include "common/compositing.glsl" +#include "common/easing.glsl" -// Scale down the window slightly. -float scale = 1.0 / mix(1.0, SCALING, progress) - 1.0; -vec2 coords = cogl_tex_coord_in[0].st * (scale + 1.0) - scale * 0.5; +uniform vec2 uSeed; +uniform vec3 uColor; +uniform float uScale; -// Get the color of the window. -cogl_color_out = texture2D(uTexture, coords); +const float WISPS_RADIUS = 20.0; +const float WISPS_SPEED = 10.0; +const float WISPS_SPACING = 40 + WISPS_RADIUS; +const int WISPS_LAYERS = 8; +const float WISPS_IN_TIME = 0.5; +const float WINDOW_OUT_TIME = 1.0; +const float SCALING = 0.9; -// Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. -if (cogl_color_out.a > 0) { - cogl_color_out.rgb /= cogl_color_out.a; +// Returns a grid of randomly moving points. Each grid cell contains one point which +// moves on an ellipse. +float getWisps(vec2 texCoords, float gridSize, vec2 seed) { + + // Shift coordinates by a random offset and make sure the have a 1:1 aspect ratio. + vec2 coords = (texCoords + hash22(seed)) * uSize; + + // Apply global scale. + coords /= gridSize; + + // Get grid cell coordinates in [0..1]. + vec2 cellUV = mod(coords, vec2(1)); + + // This is unique for each cell. + vec2 cellID = coords - cellUV + vec2(362.456); + + // Add random rotation, scale and offset to each grid cell. + float speed = mix(10.0, 15.0, hash12(cellID * seed * 134.451)) / gridSize * WISPS_SPEED; + float rotation = mix(0.0, 6.283, hash12(cellID * seed * 54.4129)); + float radius = mix(0.5, 1.0, hash12(cellID * seed * 19.1249)) * WISPS_RADIUS; + float roundness = mix(-1.0, 1.0, hash12(cellID * seed * 7.51949)); + + vec2 offset = vec2(sin(speed * (uTime + 1)) * roundness, cos(speed * (uTime + 1))); + offset *= 0.5 - 0.5 * radius / gridSize; + offset = vec2(offset.x * cos(rotation) - offset.y * sin(rotation), + offset.x * sin(rotation) + offset.y * cos(rotation)); + + cellUV += offset; + + // Use distance to center of shifted / rotated UV coordinates to draw a glaring point. + float dist = length(cellUV - 0.5) * gridSize / radius; + if (dist < 1.0) { + return min(5, 0.01 / pow(dist, 2.0)); + } + + return 0.0; } -// Compute several layers of moving wisps. -vec2 uv = (cogl_tex_coord_in[0].st - 0.5) / mix(1.0, 0.5, progress) + 0.5; -uv /= uScale; -float wisps = 0; -for (int i = 0; i < WISPS_LAYERS; ++i) { - wisps += getWisps(uv * 0.3, WISPS_SPACING, uSeed * (i + 1)); -} +void main() { + float progress = uForOpening ? 1.0 - easeOutQuad(uProgress) : easeOutQuad(uProgress); -// Compute shrinking edge mask. -float mask = getRelativeEdgeMask(mix(0.01, 0.5, progress)); + // Scale down the window slightly. + float scale = 1.0 / mix(1.0, SCALING, progress) - 1.0; + vec2 coords = cogl_tex_coord_in[0].st * (scale + 1.0) - scale * 0.5; -// Compute three different progress values. -float wispsIn = smoothstep(0, 1, clamp(progress / WISPS_IN_TIME, 0, 1)); -float wispsOut = - smoothstep(0, 1, clamp((progress - WISPS_IN_TIME) / (1.0 - WISPS_IN_TIME), 0, 1)); -float windowOut = smoothstep(0, 1, clamp(progress / WINDOW_OUT_TIME, 0, 1)); + // Get the color of the window. + cogl_color_out = texture2D(uTexture, coords); -// Use a noise function to dissolve the window. -float noise = smoothstep(1.0, 0.0, abs(2.0 * simplex2DFractal(uv * uSize / 250) - 1.0)); -float windowMask = 1.0 - (windowOut < 0.5 ? mix(0.0, noise, windowOut * 2.0) - : mix(noise, 1.0, windowOut * 2.0 - 1.0)); -cogl_color_out.a *= windowMask * mask; + // Shell.GLSLEffect uses straight alpha. So we have to convert from premultiplied. + if (cogl_color_out.a > 0) { + cogl_color_out.rgb /= cogl_color_out.a; + } -// Add the wisps. -vec4 wispColor = wisps * vec4(uColor, min(wispsIn, 1.0 - wispsOut) * mask); -cogl_color_out = alphaOver(cogl_color_out, wispColor); + // Compute several layers of moving wisps. + vec2 uv = (cogl_tex_coord_in[0].st - 0.5) / mix(1.0, 0.5, progress) + 0.5; + uv /= uScale; + float wisps = 0; + for (int i = 0; i < WISPS_LAYERS; ++i) { + wisps += getWisps(uv * 0.3, WISPS_SPACING, uSeed * (i + 1)); + } -// These are pretty useful for understanding how this works. -// cogl_color_out = vec4(vec3(windowMask), 1.0); -// cogl_color_out = vec4(vec3(wisps), 1.0); -// cogl_color_out = vec4(vec3(noise), 1.0); -// cogl_color_out = vec4(vec3(mask*min(wispsIn, 1.0 - wispsOut)), 1.0); \ No newline at end of file + // Compute shrinking edge mask. + float mask = getRelativeEdgeMask(mix(0.01, 0.5, progress)); + + // Compute three different progress values. + float wispsIn = smoothstep(0, 1, clamp(progress / WISPS_IN_TIME, 0, 1)); + float wispsOut = + smoothstep(0, 1, clamp((progress - WISPS_IN_TIME) / (1.0 - WISPS_IN_TIME), 0, 1)); + float windowOut = smoothstep(0, 1, clamp(progress / WINDOW_OUT_TIME, 0, 1)); + + // Use a noise function to dissolve the window. + float noise = smoothstep(1.0, 0.0, abs(2.0 * simplex2DFractal(uv * uSize / 250) - 1.0)); + float windowMask = 1.0 - (windowOut < 0.5 ? mix(0.0, noise, windowOut * 2.0) + : mix(noise, 1.0, windowOut * 2.0 - 1.0)); + cogl_color_out.a *= windowMask * mask; + + // Add the wisps. + vec4 wispColor = wisps * vec4(uColor, min(wispsIn, 1.0 - wispsOut) * mask); + cogl_color_out = alphaOver(cogl_color_out, wispColor); + + // These are pretty useful for understanding how this works. + // cogl_color_out = vec4(vec3(windowMask), 1.0); + // cogl_color_out = vec4(vec3(wisps), 1.0); + // cogl_color_out = vec4(vec3(noise), 1.0); + // cogl_color_out = vec4(vec3(mask*min(wispsIn, 1.0 - wispsOut)), 1.0); +} \ No newline at end of file diff --git a/src/Apparition.js b/src/Apparition.js index f2f3ad5..f2d61ea 100644 --- a/src/Apparition.js +++ b/src/Apparition.js @@ -164,11 +164,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${Apparition.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${Apparition.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } }); } \ No newline at end of file diff --git a/src/BrokenGlass.js b/src/BrokenGlass.js index eb27248..720faf2 100644 --- a/src/BrokenGlass.js +++ b/src/BrokenGlass.js @@ -201,11 +201,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${BrokenGlass.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${BrokenGlass.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } // This is overridden to bind the shard texture for drawing. Sadly, this seems to be diff --git a/src/EnergizeA.js b/src/EnergizeA.js index 2eb52b4..31765e9 100644 --- a/src/EnergizeA.js +++ b/src/EnergizeA.js @@ -152,11 +152,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${EnergizeA.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${EnergizeA.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } }); } \ No newline at end of file diff --git a/src/EnergizeB.js b/src/EnergizeB.js index 00dadff..3ca02bd 100644 --- a/src/EnergizeB.js +++ b/src/EnergizeB.js @@ -152,11 +152,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${EnergizeB.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${EnergizeB.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } }); } \ No newline at end of file diff --git a/src/Fire.js b/src/Fire.js index e97821f..f6477b8 100644 --- a/src/Fire.js +++ b/src/Fire.js @@ -279,10 +279,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = utils.loadGLSLResource(`/shaders/${Fire.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${Fire.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } }); } \ No newline at end of file diff --git a/src/Hexagon.js b/src/Hexagon.js index 5814d9c..d617b8e 100644 --- a/src/Hexagon.js +++ b/src/Hexagon.js @@ -171,11 +171,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${Hexagon.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${Hexagon.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } }); } \ No newline at end of file diff --git a/src/Matrix.js b/src/Matrix.js index d281873..9ec177d 100644 --- a/src/Matrix.js +++ b/src/Matrix.js @@ -183,11 +183,16 @@ if (utils.isInShellProcess()) { // https://www.shadertoy.com/view/ldccW4, however the implementation is quite // different as the letters drop only once and there is no need for a noise texture. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${Matrix.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${Matrix.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } // This is overridden to bind the font texture for drawing. Sadly, this seems to be diff --git a/src/SnapOfDisintegration.js b/src/SnapOfDisintegration.js index e604512..8570ccb 100644 --- a/src/SnapOfDisintegration.js +++ b/src/SnapOfDisintegration.js @@ -177,12 +177,17 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = utils.loadGLSLResource( - `/shaders/${SnapOfDisintegration.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${SnapOfDisintegration.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } // This is overridden to bind the dust texture for drawing. Sadly, this seems to be diff --git a/src/TRexAttack.js b/src/TRexAttack.js index 4880395..18e5083 100644 --- a/src/TRexAttack.js +++ b/src/TRexAttack.js @@ -179,11 +179,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${TRexAttack.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${TRexAttack.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } // This is overridden to bind the claw texture for drawing. Sadly, this seems to be diff --git a/src/TVEffect.js b/src/TVEffect.js index 014ffe7..f05cf78 100644 --- a/src/TVEffect.js +++ b/src/TVEffect.js @@ -148,11 +148,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${TVEffect.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${TVEffect.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } }); } \ No newline at end of file diff --git a/src/Wisps.js b/src/Wisps.js index 46dffca..ad6a30a 100644 --- a/src/Wisps.js +++ b/src/Wisps.js @@ -158,11 +158,16 @@ if (utils.isInShellProcess()) { // This is called by the constructor. This means, it's only called when the effect // is used for the first time. vfunc_build_pipeline() { - const decl = - utils.loadGLSLResource(`/shaders/${Wisps.getNick()}-declarations.glsl`); const code = utils.loadGLSLResource(`/shaders/${Wisps.getNick()}.glsl`); - this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, decl, code, true); + // Match anything between the curly brackets of "void main() {...}". + const regex = RegExp('void main *\\(\\) *\\{([\\S\\s]+)\\}', 'd'); + const match = regex.exec(code); + + const declarations = code.substr(0, match.index); + const main = match[1]; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, declarations, main, true); } }); } \ No newline at end of file diff --git a/src/utils.js b/src/utils.js index 078be68..56981fe 100644 --- a/src/utils.js +++ b/src/utils.js @@ -106,7 +106,9 @@ function loadGLSLResource(path) { // This regex matches either #include "..." or #include <...>. The part between the // brackets is captured in the named "file" capture group. - code = code.replaceAll(/#include ["<](?.+)[">]/g, (m, p1, p2, str, groups) => { + const regex = RegExp('#include ["<](?.+)[">]', 'g'); + + code = code.replaceAll(regex, (m, p1, p2, str, groups) => { return loadStringResource('/shaders/' + groups.file); });