1
\$\begingroup\$

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: enter image description here https://twitter.com/i/status/992811158318075904

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

Here the fog is more subtle and denser near the ground: enter image description here 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?

\$\endgroup\$
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ – Sidar Jun 23 '18 at 18:41
  • \$\begingroup\$ @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? \$\endgroup\$ – GoldenGremlin Jun 23 '18 at 19:45
2
\$\begingroup\$

I made a little demo :

Edit:

-Extra version: Applied with color banding

-Even better version : inverted the uv mapping as @Mario suggested

-Better version: Texture addressing/Wrapping set to Mirror - still fades on overlap

-First version: Texture addressing/Wrapping set to Repeat, non repeating texture

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

enter image description here

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.