shader_type spatial;
render_mode unshaded, blend_mix, depth_draw_never, cull_disabled, shadows_disabled;

// Alpha-blended soft puff (dust, smoke, poof clouds). Billboarded; colour * particle COLOR.
uniform vec4 color : source_color = vec4(1.0);
uniform float softness = 1.4;
// CC0 Kenney smoke sprite (assets/fx/kenney): tex_mix 0 = the plain cartoon puff, 1 = the sprite's wispy shape;
// each puff gets its own rotation (from its world position).
uniform sampler2D tex : hint_default_white, filter_linear_mipmap, repeat_disable;
uniform float tex_mix = 0.0;
varying float v_ang;

void vertex() {
	vec3 o = MODEL_MATRIX[3].xyz;
	v_ang = fract(sin(dot(o, vec3(12.9898, 78.233, 37.719))) * 43758.5453) * 6.2831853;
	mat4 mw = mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);
	MODELVIEW_MATRIX = VIEW_MATRIX * mw;
	MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(
		vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0),
		vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0),
		vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0),
		vec4(0.0, 0.0, 0.0, 1.0));
}

void fragment() {
	vec2 p = UV * 2.0 - 1.0;
	float r = length(p);
	// lumpy cartoon cloud: a bright top, cel-ish edge
	float a = 1.0 - smoothstep(1.0 - 0.35 * softness, 1.0, r);
	if (tex_mix > 0.0) {
		vec2 q = mat2(vec2(cos(v_ang), sin(v_ang)), vec2(-sin(v_ang), cos(v_ang))) * (UV - 0.5) + 0.5;
		float t = texture(tex, q).a;
		a = mix(a, clamp(t * 1.6, 0.0, 1.0) * (1.0 - smoothstep(0.85, 1.0, r)), tex_mix);
	}
	vec4 c = color * COLOR;
	ALBEDO = c.rgb * mix(0.85, 1.08, clamp(-p.y * 0.5 + 0.5, 0.0, 1.0));
	ALPHA = a * c.a;
}
