Files

134 lines
7.8 KiB
KDL

// Burn Effect with Ashes - Windows burn with 8 random ember colors, floating ash, and glowing sparks
//
// Adjustable parameters:
// - uv * 8.0: Edge roughness - higher = finer burn pattern
// - threshold * 0.8: Burn reach - how far burn extends into window
// - 0.08: Glow width - width of ember glow line
// - 150.0 in ash_particle: Ash size - higher = smaller particles
// - 280.0 in ember_spark: Spark size - higher = smaller sparks
// - Loop counts (7.0, 8.0): Particle layers - more = more particles (performance impact)
animations {
window-open {
duration-ms 400
curve "linear"
custom-shader r"
float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }
float noise(vec2 p) {
vec2 i = floor(p); vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),
mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x), f.y);
}
vec3 get_ember_colors(float seed, out vec3 inner, out vec3 outer) {
if (seed < 0.125) { inner = vec3(1.0, 0.3, 0.0); outer = vec3(1.0, 0.8, 0.2); } // orange
else if (seed < 0.250) { inner = vec3(0.2, 0.4, 1.0); outer = vec3(0.5, 0.8, 1.0); } // blue
else if (seed < 0.375) { inner = vec3(0.6, 0.1, 0.9); outer = vec3(0.9, 0.5, 1.0); } // purple
else if (seed < 0.500) { inner = vec3(0.1, 0.8, 0.2); outer = vec3(0.5, 1.0, 0.3); } // green
else if (seed < 0.625) { inner = vec3(1.0, 0.1, 0.4); outer = vec3(1.0, 0.5, 0.7); } // pink
else if (seed < 0.750) { inner = vec3(0.0, 0.8, 0.9); outer = vec3(0.7, 1.0, 1.0); } // cyan
else if (seed < 0.875) { inner = vec3(0.9, 0.7, 0.1); outer = vec3(1.0, 1.0, 0.8); } // gold
else { inner = vec3(0.8, 0.2, 0.1); outer = vec3(1.0, 0.5, 0.2); } // red
return inner;
}
vec4 open_color(vec3 coords_geo, vec3 size_geo) {
if (coords_geo.x < 0.0 || coords_geo.x > 1.0 || coords_geo.y < 0.0 || coords_geo.y > 1.0) return vec4(0.0);
float progress = niri_clamped_progress;
vec2 uv = coords_geo.xy;
vec3 coords_tex = niri_geo_to_tex * vec3(uv, 1.0);
vec4 color = texture2D(niri_tex, coords_tex.st);
float edge_dist = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));
float n = noise(uv * 8.0 + niri_random_seed * 100.0) * 0.3;
float burn_line = edge_dist + n;
float threshold = progress * 0.8;
vec3 ember_inner, ember_outer;
get_ember_colors(niri_random_seed, ember_inner, ember_outer);
if (burn_line < threshold - 0.08) return color;
else if (burn_line < threshold) {
vec3 ember = mix(ember_inner, ember_outer, (burn_line - threshold + 0.08) / 0.08);
return vec4(mix(ember, color.rgb, 0.3), color.a);
} else return vec4(0.0);
}
"
}
window-close {
duration-ms 600
curve "linear"
custom-shader r"
float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }
float noise(vec2 p) {
vec2 i = floor(p); vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),
mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x), f.y);
}
vec3 get_ember_colors(float seed, out vec3 inner, out vec3 outer) {
if (seed < 0.125) { inner = vec3(1.0, 0.3, 0.0); outer = vec3(1.0, 0.8, 0.2); }
else if (seed < 0.250) { inner = vec3(0.2, 0.4, 1.0); outer = vec3(0.5, 0.8, 1.0); }
else if (seed < 0.375) { inner = vec3(0.6, 0.1, 0.9); outer = vec3(0.9, 0.5, 1.0); }
else if (seed < 0.500) { inner = vec3(0.1, 0.8, 0.2); outer = vec3(0.5, 1.0, 0.3); }
else if (seed < 0.625) { inner = vec3(1.0, 0.1, 0.4); outer = vec3(1.0, 0.5, 0.7); }
else if (seed < 0.750) { inner = vec3(0.0, 0.8, 0.9); outer = vec3(0.7, 1.0, 1.0); }
else if (seed < 0.875) { inner = vec3(0.9, 0.7, 0.1); outer = vec3(1.0, 1.0, 0.8); }
else { inner = vec3(0.8, 0.2, 0.1); outer = vec3(1.0, 0.5, 0.2); }
return inner;
}
float ash_particle(vec2 uv, float seed) {
float pn = noise(uv * 150.0 + seed * 50.0);
return pn < 0.78 ? 0.0 : (pn - 0.78) / 0.22;
}
float ember_spark(vec2 uv, float seed) {
float sn = hash(floor(uv * 280.0) + seed * 100.0);
return sn < 0.982 ? 0.0 : pow((sn - 0.982) / 0.018, 2.0);
}
vec4 close_color(vec3 coords_geo, vec3 size_geo) {
float progress = niri_clamped_progress;
vec2 uv = coords_geo.xy;
vec3 ember_inner, ember_outer;
get_ember_colors(niri_random_seed, ember_inner, ember_outer);
vec4 particles = vec4(0.0);
for (float i = 0.0; i < 7.0; i++) {
float ls = niri_random_seed + i * 0.1;
vec2 auv = uv; auv.y += progress * (0.25 + i * 0.12);
auv.x += progress * (noise(vec2(i, ls) * 10.0) - 0.5) * 0.4 + sin(progress * 6.28 + i * 1.5) * 0.03;
float ed = min(min(auv.x, 1.0 - auv.x), min(auv.y, 1.0 - auv.y));
float sz = progress * 0.75;
if (ed < sz && ed > 0.0) {
float p = ash_particle(auv, ls);
float fade = (1.0 - smoothstep(0.0, sz, ed)) * (1.0 - progress * 0.4);
particles.rgb += mix(ember_outer * 0.5, vec3(0.3), 0.4 + i * 0.1) * p * fade * 0.7;
particles.a += p * fade * 0.5;
}
}
for (float j = 0.0; j < 8.0; j++) {
float ss = niri_random_seed + j * 0.17 + 0.5;
vec2 suv = uv; suv.y += progress * (0.4 + j * 0.1);
suv.x += progress * (hash(vec2(j, ss)) - 0.5) * 0.5 + sin(progress * 10.0 + j * 2.0) * 0.025;
float ed = min(min(suv.x, 1.0 - suv.x), min(suv.y, 1.0 - suv.y));
float sz = progress * 0.7;
if (ed < sz && ed > 0.0) {
float sp = ember_spark(suv, ss);
float fade = (1.0 - smoothstep(0.0, sz * 0.8, ed)) * (1.0 - progress * 0.6);
float flicker = 0.7 + 0.3 * sin(progress * 20.0 + j * 3.0);
particles.rgb += ember_inner * sp * fade * flicker * 1.5;
particles.a += sp * fade * 0.8;
}
}
if (coords_geo.x < 0.0 || coords_geo.x > 1.0 || coords_geo.y < 0.0 || coords_geo.y > 1.0) return particles;
vec3 coords_tex = niri_geo_to_tex * vec3(uv, 1.0);
vec4 color = texture2D(niri_tex, coords_tex.st);
float edge_dist = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));
float n = noise(uv * 8.0 + niri_random_seed * 100.0) * 0.3;
float burn_line = edge_dist + n;
float threshold = progress * 0.8;
if (burn_line > threshold + 0.08) return color + particles;
else if (burn_line > threshold) {
vec3 ember = mix(ember_inner, ember_outer, 1.0 - (burn_line - threshold) / 0.08);
return vec4(mix(ember, color.rgb, 0.3), color.a) + particles;
} else return particles;
}
"
}
}