60 lines
1.6 KiB
Plaintext
60 lines
1.6 KiB
Plaintext
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);
|
|
}
|