Settings

Theme

Show HN: WebGL Fire Simulation

ghostinthecode.net

143 points by jharsman 10 years ago · 24 comments

Reader

kbirk 10 years ago

Nothing will ever impress me more than this WebGL fire / explosion effect: http://glslsandbox.com/e#33550.0

Warning: may melt your GPU.

  • Silhouette 10 years ago

    Warning: may melt your GPU.

    You're not wrong. That put a workstation-class GPU in a water-cooled system up about 20 degrees C within a few seconds. And it was still not fast enough to animate smoothly during the more demanding parts later in the sequence.

    Awesome effect, though. :-)

  • dr_zoidberg 10 years ago

    It worked beautiful on my Intel HD 4000, though setting the "quality" to 1 or 0.5 did slow things down quite a bit.

  • abritinthebay 10 years ago

    Works surprisingly well on iOS actually! Not as good as desktop but the effect is impressive

  • n00b101 10 years ago

    This crashed my NVIDIA driver.

jstsch 10 years ago

Did something similar a few years ago... a port of the classic demo effect to JS/Canvas :) https://jstsch.com/post/old-skool_fire_demo_effect_in_javasc...

velcro 10 years ago

Takes me back to the time of Netscape 2.0 where webpages were not complete without a fire.gif background :)

BTW did a pure CSS3 fire a while ago too: http://pag.es/fire/test.html

s-macke 10 years ago

If you want to see fire based on real fluid dynamics take a look at Ron Fedkiw's site: http://physbam.stanford.edu/~fedkiw/

For example the following video: http://physbam.stanford.edu/~fedkiw/animations/fireball.avi

andypants 10 years ago

Parts of it look way too noisy, like TV static.

  • jharsmanOP 10 years ago

    Yes, the actual burning fuel part is just random noise, which doesn't look very very good. I mention it as a possible imrpovement under "Better looking fuel".

  • mrspeaker 10 years ago

    I seem to remember reading a tutorial about making this effect back in the 90s (it was a great series by someone called "Denthor", or something like that). The bottom part of the effect was supposed to be hidden, only showing the flames I think.

heywire 10 years ago

I remember doing something similar in x86 assembly back in the 90's. int 10h comes to mind.

  • acz 10 years ago

    Oh me too, was fun and surprisingly not difficult. Still remember learning cool tricks from the Hugi demoscene diskmag.

kruhft 10 years ago

Having fun playing with fire:

https://twitter.com/kruhft/status/766304583924592640

CommanderData 10 years ago

Looks like Runescape fire.

WhitneyLand 10 years ago

Nice work. Effects like these are a great example of programmers combining theory, art, and creative optimizations.

steaminghacker 10 years ago

do you have a shadertoy version of this for comparison?

i took this one by ozzy https://www.shadertoy.com/view/lsSGWw 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.

like this:

#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)

        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;
        }
  • jharsmanOP 10 years ago

    I can't get your example code to work, but that is a completely different technique, ray marching a volume displaced by a noise function. This gives nice 3D-looking flames, but the movement tends to look like a scrolling noise function. And it's harder to use arbitrary burning shapes, my simulation supports drawing anything and it will burn.

    • steaminghacker 10 years ago

      Sorry, this version wont just paste back as is in shadertoy. Also it needs a random 256x256 bitmap in channel 0. The effect is the same as ozzy's original, except change ITERATIONS to 13 in his code to see the change (which is only slightly better). The other changes were for performance, which i improved slightly.

  • anewhnaccount 10 years ago

    Maybe make a shadertoy and post a link?

mirimir 10 years ago

Is there any way to see the result without WebGL?

uwu 10 years ago

can i have this for selected text?

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection