Nothing will ever impress me more than this WebGL fire / explosion effect: <a href="http://glslsandbox.com/e#33550.0" rel="nofollow">http://glslsandbox.com/e#33550.0</a><p>Warning: may melt your GPU.
Did something similar a few years ago... a port of the classic demo effect to JS/Canvas :) <a href="https://jstsch.com/post/old-skool_fire_demo_effect_in_javascriptcanvas" rel="nofollow">https://jstsch.com/post/old-skool_fire_demo_effect_in_javasc...</a>
Takes me back to the time of Netscape 2.0 where webpages were not complete without a fire.gif background :)<p>BTW did a pure CSS3 fire a while ago too:
<a href="http://pag.es/fire/test.html" rel="nofollow">http://pag.es/fire/test.html</a>
If you want to see fire based on real fluid dynamics take a look at Ron Fedkiw's site: <a href="http://physbam.stanford.edu/~fedkiw/" rel="nofollow">http://physbam.stanford.edu/~fedkiw/</a><p>For example the following video: <a href="http://physbam.stanford.edu/~fedkiw/animations/fireball.avi" rel="nofollow">http://physbam.stanford.edu/~fedkiw/animations/fireball.avi</a>
Having fun playing with fire:<p><a href="https://twitter.com/kruhft/status/766304583924592640" rel="nofollow">https://twitter.com/kruhft/status/766304583924592640</a>
do you have a shadertoy version of this for comparison?<p>i took this one by ozzy <a href="https://www.shadertoy.com/view/lsSGWw" rel="nofollow">https://www.shadertoy.com/view/lsSGWw</a>
and tweaked a few things by hand for optimization. saved a few cycles on the code and increased the iterations to 13, which gives a better result.<p>like this:<p>#define ITERATIONS 13.0
#define SPEED 10.0
#define DISPLACEMENT 0.05
#define YOFFSET 0.1
#define YSCALE 0.25
#define FLAMETONE vec3(50.0, 5.0, 1.0)<p><pre><code> uniform lowp sampler2D source; // this item
uniform lowp sampler2D chan0; // random map
uniform lowp float qt_Opacity; // inherited opacity of this item
varying highp vec2 qt_TexCoord0;
uniform highp float time; // shader playback time (in seconds)
float noise( in vec3 x ) // iq noise function
{
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;
vec2 rg = texture2D( chan0, (uv + 0.5)/256.0, -100.0 ).yx;
return mix( rg.x, rg.y, f.z ) * 2.0 - 1.0;
}
void main()
{
vec2 uv = vec2(qt_TexCoord0.s, (1.0 - qt_TexCoord0.t));
float nx = 0.0;
float ny = 0.0;
float i;
for (i=1.0; i<=ITERATIONS; i = i + 1.0)
{
float ifrac = i/ITERATIONS;
float d = (1.0-ifrac) * DISPLACEMENT;
ifrac *= time;
float ii = i*i;
float y = uv.y*YSCALE*ii - ifrac * SPEED;
float x = uv.x*ii;
nx += noise( vec3(x-ifrac, y, 0.0)) * d * 2.0;
ny += noise( vec3(x+ifrac, y, ifrac/ii)) * d;
}
uv.x += nx;
uv.y += ny;
// a blob shape to distort
float flame = clamp( sin(uv.x*3.1416) - uv.y+YOFFSET, 0.0, 1.0 );
flame *= flame; // f^2
float ft = flame*flame; // f^4
flame *= ft*ft; // f^10
//lowp vec3 col = pow(flame, TIGHTNESS) * FLAMETONE;
lowp vec3 col = flame * FLAMETONE;
// tonemapping
col = col / (1.0+col);
// ~sqrt
//col = pow(col, vec3(1.0/2.2));
col = sqrt(col);
col = clamp(col, 0.0, 1.0);
lowp vec4 p = texture2D(source, qt_TexCoord0);
p.xyz = col;
gl_FragColor = p * qt_Opacity;
}</code></pre>