shader_type canvas_item; uniform sampler2D noise_tex : source_color; uniform float time_speed = 1.5; uniform float distortion_amount = 0.12; uniform float flame_height = 1.4; uniform vec4 inner_color : source_color = vec4(1.0, 0.9, 0.4, 1.0); // hot core uniform vec4 outer_color : source_color = vec4(1.0, 0.4, 0.0, 1.0); // orange rim void fragment() { vec2 uv = UV; // Make the flame taller uv.y *= flame_height; float t = TIME * time_speed; // Sample noise that scrolls upward vec2 noise_uv = mod(vec2(uv.x, uv.y + t * 0.6), vec2(1.0)); float n = texture(noise_tex, noise_uv).r; // Horizontal distortion based on noise uv.x += (n - 0.5) * distortion_amount; // Slight vertical wobble uv.y -= (n - 0.5) * 0.1; // Remap coords so bottom center is the origin vec2 p = uv - vec2(0.5, 1.0); // Elliptical falloff (wider at base) float dist = length(vec2(p.x * 1.8, p.y * 1.2)); // Base flame shape (soft circle-ish blob) float core = smoothstep(0.9, 0.0, dist); // Only show above the base (cut off below) float cutoff = smoothstep(-0.2, 0.2, p.y); // fade out below the base core *= cutoff; // Extra shaping towards the tip (thinner at top) float tip = smoothstep(0.0, 0.7, uv.y); core *= tip; // Final intensity float intensity = core; if (intensity <= 0.001) { discard; } // Color blend from outer to inner vec4 col = mix(outer_color, inner_color, intensity); // Alpha from intensity float alpha = clamp(intensity, 0.0, 1.0); COLOR = vec4(col.rgb * intensity * 2.0, alpha); }