Randoloot/scripts/game/burning_gas.gdshader
2026-10-25 22:38:13 +01:00

61 lines
2.1 KiB
Plaintext

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