shader_type canvas_item; render_mode unshaded; uniform vec4 plume_color : source_color = vec4(0.1,0.65,1.0,1.0); uniform float power = 0.0; uniform float boost = 0.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),f=fract(p); f=f*f*(3.0-2.0*f); return mix(mix(hash(i),hash(i+vec2(1,0)),f.x),mix(hash(i+vec2(0,1)),hash(i+vec2(1)),f.x),f.y); } void fragment() { float y=UV.y; float length=mix(0.30,0.85,boost)*(0.55+power*0.45); float travel=y/max(length,0.01); float turbulence=noise(vec2(y*18.0-TIME*24.0,phase+TIME*2.0)); float width=max(0.018,0.33*pow(max(0.0,1.0-travel),0.65)); float center=0.5+(turbulence-0.5)*0.11*travel; float dist=abs(UV.x-center); float body=1.0-smoothstep(width*0.22,width,dist); float end=1.0-smoothstep(0.65,1.0,travel); float core=exp(-dist*dist/max(0.0001,width*width*0.045))*(1.0-smoothstep(0.15,0.65,travel)); float diamonds=pow(max(0.0,cos(travel*33.0-TIME*7.0)),6.0)*boost*0.22; vec3 color=mix(plume_color.rgb,vec3(0.8,0.95,1.0),core*0.9+diamonds); float halo=exp(-dist*dist*18.0)*exp(-y*7.0)*0.13; COLOR=vec4(color,(body*end*(0.62+turbulence*0.22)+halo)*power); }