Files
Burn-My-Windows/resources/shaders/broken-glass.glsl
T
2022-05-13 09:17:26 +02:00

67 lines
2.4 KiB
GLSL

// 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;
void main() {
cogl_color_out = vec4(0, 0, 0, 0);
float progress = uForOpening ? 1.0 - uProgress : uProgress;
// Draw the individual shard layers.
for (float i = 0; i < SHARD_LAYERS; ++i) {
// 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;
// Scale and rotate around our epicenter.
coords -= uEpicenter;
// Scale each layer a bit differently.
coords /= mix(1.0, 1.0 + uBlowForce * (i + 2) / SHARD_LAYERS, progress);
// 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));
// Move down each layer a bit.
float gravity =
(uForOpening ? -1.0 : 1.0) * uGravity * 0.1 * (i + 1) * progress * progress;
coords += vec2(0, gravity);
// 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;
}
}