/* fire.sl * * animated fire -- adpated from shader by Flip Phillips * */ #include "rmannotes.sl" surface fire(float frame = 1) { color layer_color, surface_color; color surface_opac, layer_opac; float width, cutoff, fade, f, turb, maxfreq = 16; float flame; float ss, tt; color red = color (1, .3, .1); color orange = color (.95, .7, .05); color yellow = color (.95, .95, .1); color hot = color (1, 1, .8); surface_color = 0; surface_opac = 0; /* compress ss & offset both by factor of current frame */ ss = s * 5 + frame * 0.01; tt = t + frame * 0.1; /* compute turbulence */ width = max(filterwidth(ss), filterwidth(tt)); cutoff = clamp(0.5 / width, 0, maxfreq); turb = 0; for (f = 1; f < 0.5 * cutoff; f *= 2) turb += abs(snoise2(ss * f, tt * f)) / f; fade = clamp(2 * (cutoff - f) / cutoff, 0, 1); turb += fade * abs(snoise2(ss * f, tt * f)) / f; turb *= 0.5; /* index into color spline using turbulence */ flame = clamp(t - turb, 0, 1); layer_opac = flame; layer_color = spline(flame, red, red, red, red, orange, yellow, hot, hot); surface_color = blend(surface_color, layer_color, layer_opac); surface_opac = union(surface_opac, layer_opac); /* output */ Oi = surface_opac; Ci = surface_color; }