How to create a 2D fog shader?

I am trying to write a fragment shader in GLSL for a fog effect in a 2D game.

Here are some links showing what I'm after.

Here the fog is in the foreground and near the ground: https://twitter.com/i/status/992811158318075904

Here the fog is on a background layer and fills the screen: https://twitter.com/i/status/963889084337983488

Here the fog is more subtle and denser near the ground: https://twitter.com/i/status/1001926421856563205

I am interested in learning how to create these effects. Unfortunately, I am pretty new to shaders and only know how to do elementary stuff like color swaps, outlines, and simple vignettes. It doesn't help that it's hard to find resources on shaders with a bent toward 2D.

In the environment in which I'm working, I can attach a shader script to any of my sprites, parallax background layers, etc.

Does anyone have advice on creating these kinds of effects?

• Im not sure about the color banding, but you could easily achieve such an effect by using a noise/cloudy map. You could animate not just by moving it but by sampling twice with 2 different uv coordinates. Ill see if I can work on a demo – Sidar Jun 23 '18 at 18:41
• @Sidar, thanks for the response. I would really appreciate that! Or just an explanation of what you mean by noise/cloudy map. I assume you mean take a noise image and use it to alter the target image? – GoldenGremlin Jun 23 '18 at 19:45

I made a little demo :

Edit:

Basically what I've done here is taken a noise map ( source ):

And sampled it twice with 2 different uv coordinates ( see quad.frag.glsl ). In my example I just used a timer to offset in positive and negative direction. Then simply subtracted the second sample from the first.

vec4 n = texture(iTex,uv+iTime*0.1);
vec4 n2 = texture(iTex,uv-iTime*0.1);
n-=n2;
fragColor = n;


improved version using Mirror addressing and uv swapping;

vec4 n = texture(iTex,uv+iTime*0.1);
vec4 n2 = texture(iTex,vec2(uv.y,uv.x)-iTime*0.1);
n-=n2;
fragColor = n;


Alternatively you could have a second noise map and offset/subtract from the first image, or use an actual perlin noise function and calculate two different values. If you play around with this concept I'm sure you'll find something satisfactory. How you blend and color it is all up to you. It doesn't have to be a noise map, could be any arbitrary grey scale image.

I hope others can provide their solutions too, I too am interested in this concept further.

edit:

Here is an example with perlin noise

and with color

I snatched the code from computergraphics

• Overlapping issue: Why not simply inverting one coordinate for n2? – Mario Jun 24 '18 at 6:53
• Eh that should work too – Sidar Jun 24 '18 at 10:09
• @Mario added the suggestion works better – Sidar Jun 24 '18 at 11:41