shader_type canvas_item; render_mode unshaded; uniform float age = 0.0; uniform float strength = 1.0; uniform float phase = 0.0; float hash(vec2 p) { p = fract(p * vec2(123.34, 456.21)); p += dot(p, p + 45.32); return fract(p.x * p.y); } 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)), f.x), f.y); } float fbm(vec2 p) { float value = 0.0; float weight = 0.5; mat2 turn = mat2(vec2(0.8, -0.6), vec2(0.6, 0.8)); for (int i = 0; i < 4; i++) { value += noise(p) * weight; p = turn * p * 2.03 + vec2(7.1, 3.7); weight *= 0.5; } return value; } void fragment() { vec2 p = (UV - 0.5) * 2.0; float t = age * 0.65; vec2 drift = vec2(t * 0.18, -t * 0.26); vec2 q = vec2(fbm(p * 2.6 + drift + phase), fbm(p * 2.6 - drift + 12.4 + phase)); vec2 curled = p * 4.2 + (q - 0.5) * 3.3; float billow = fbm(curled + vec2(-t * 0.35, t * 0.5)); float detail = fbm(curled * 2.2 - vec2(t * 0.6, t * 0.35)); float radius = length(p); float edge = radius + (q.x - 0.5) * 0.25 + (billow - 0.5) * 0.15; float silhouette = 1.0 - smoothstep(0.62, 0.88, edge); float core = 1.0 - smoothstep(0.1, 0.8, radius); float heat = clamp(billow * 1.05 + detail * 0.32 + core * 0.22 - 0.25, 0.0, 1.0); float fire = smoothstep(0.27, 0.58, heat) * silhouette; float veins = pow(1.0 - abs(detail * 2.0 - 1.0), 5.0); float hot = smoothstep(0.48, 0.82, heat + veins * 0.16); vec3 flame = mix(vec3(0.65, 0.055, 0.004), vec3(1.2, 0.32, 0.015), smoothstep(0.2, 0.5, heat)); flame = mix(flame, vec3(1.55, 0.91, 0.29), hot); flame = mix(flame, vec3(1.7, 1.35, 0.82), pow(hot, 4.0) * 0.65); vec3 smoke = mix(vec3(0.025, 0.028, 0.035), vec3(0.16, 0.095, 0.052), billow); float smoke_alpha = silhouette * (0.4 + billow * 0.4); float glow = exp(-radius * radius * 5.0) * 0.20; vec3 color = mix(smoke, flame, fire); color += vec3(0.4, 0.075, 0.005) * glow; float alpha = max(smoke_alpha, fire * 0.95) + glow * (1.0 - silhouette); COLOR = vec4(color, clamp(alpha * strength, 0.0, 1.0)); }