// La faille d'une entree sci-fi (ligne 81): une fissure lumineuse et dentelee,
// posee a plat sur le sol. `opening` l'ouvre de 0 (fermee) a 1 (beante).
// UV.x court le long de la fissure, UV.y en travers. Rien a dessiner: tout est
// calcule, et la graine change le trace d'une creature a l'autre.
shader_type spatial;
render_mode unshaded, blend_add, cull_disabled, depth_draw_never, shadows_disabled;

uniform vec4 glow_color : source_color = vec4(0.62, 0.32, 1.0, 1.0);
uniform vec4 core_color : source_color = vec4(0.82, 1.0, 1.0, 1.0);
uniform float opening : hint_range(0.0, 1.0) = 0.0;
uniform float seed = 0.0;
uniform float pulse = 0.0;
// An upright narrative portal has a dark interior. Creature entrances keep
// the original filled fissure because this option defaults to false.
uniform bool hollow = false;
uniform float jaggedness : hint_range(0.0, 1.0) = 1.0;

float hash(float n) {
	return fract(sin(n * 12.9898 + seed * 78.233) * 43758.5453);
}

float wobble(float x) {
	float i = floor(x);
	float f = fract(x);
	return mix(hash(i), hash(i + 1.0), f);
}

void fragment() {
	float x = UV.x;
	// Une ligne brisee: des segments droits, pas une ondulation molle.
	float centre = 0.5 + ((wobble(x * 9.0) - 0.5) * 0.34 + (wobble(x * 27.0 + 3.1) - 0.5) * 0.10) * jaggedness;
	// La fissure s'amincit vers ses bouts.
	float ends = smoothstep(0.0, 0.2, x) * smoothstep(1.0, 0.8, x);
	float half_width = opening * 0.1 * ends;
	float d = abs(UV.y - centre);
	float core = (1.0 - smoothstep(half_width * 0.35, half_width + 0.002, d)) * step(0.001, opening);
	float halo = exp(-d / max(0.001, 0.025 + opening * 0.09)) * ends * opening;
	if (hollow) {
		core *= smoothstep(half_width * 0.35, half_width * 0.8, d);
		halo *= smoothstep(half_width * 0.35, half_width, d);
	}
	vec3 colour = core_color.rgb * core * 1.6 + glow_color.rgb * halo * (1.3 + pulse * 0.7);
	ALBEDO = colour;
	ALPHA = clamp(core + halo, 0.0, 1.0);
}
