Files
zfxaction25/DonkeysAndDroids.Godot/flame.gdshader
2026-04-19 00:43:27 +02:00

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);
}