67 lines
2.4 KiB
GLSL
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;
|
|
}
|
|
} |