Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: WebGL Fire Simulation (ghostinthecode.net)
143 points by jharsman on Aug 18, 2016 | hide | past | favorite | 23 comments



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

Warning: may melt your GPU.


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. :-)


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


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


This crashed my NVIDIA driver.


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...


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


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


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


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".


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.


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


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



Looks like Runescape fire.


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


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


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.


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.


Maybe make a shadertoy and post a link?


Is there any way to see the result without WebGL?


can i have this for selected text?


[flagged]


We've banned this account for repeatedly violating the guidelines.

https://news.ycombinator.com/newsguidelines.html




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: