• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker Dynamic Fog

Gamerev147

Member
I've been trying to make a dynamic fog type of effect. Everything I've seen so far is all using foreground noise images to simulate fog.

I wanted to make a dynamic fog effect, where the fog looks like natural fog (random).
I was also messing around with shaders and got one that looks okay. However, it's not transparent in between the fog.

Any help would be greatly appreciated. Thanks!
 
Shader is the best bet. What do you mean not transparent, is it black or is the fog so thick their are no open spots in the fog. You could try lowering the alpha channel in the shader for one thing.

Maybe post your shader code if possible and a screenshot of what you are currently getting.
 

NightFrost

Member
For a dynamic fog, shader should be the best bet. They generate it by smoothstepping output from pseudorandom noise generators, combining different octaves and frequencies (aka fractal brownian motion). You can just treat it as a black box if you don't want to read up on the concepts... As far as I've understood you can see them called differently either as value noise or perlin noise, depending on how the pseudorandom noise generator works, but the noise source seems to make little difference. As for the transparency, your fog needs to draw fog colour and use the value the FBM pops out as alpha. Something like gl_FragColor = vec4(vec3(1.0), noise).
 

Gamerev147

Member
@NightFrost
@IndianaBones

As of now, this is the shader I am using:
sh_Fog
Code:
attribute vec3 in_Position;                  // (x,y,z)
//attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
//attribute vec4 in_Colour;                    // (r,g,b,a) unused in this shader.
[ATTACH]25177[/ATTACH]
[ATTACH]25177[/ATTACH]
//attribute vec2 in_TextureCoord;              // (u,v)     unused in this shader.

varying vec2 fragCoord;

void main()
{
    vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;

    fragCoord = in_Position.xy;
}
Code:
//SETTINGS//
const float timeScale = 10.0;
const float cloudScale = 0.4;
const float skyCover = .6; //In the future, make this dynamic
const float softness = 0.2;
const float brightness = 0.2;
const int noiseOctaves = 7;
const float curlStrain = 3.0;

varying vec2 fragCoord;

uniform float runTime;

float saturate(float num)
{
    return clamp(num,0.0,1.0);
}

float noise(vec2 uv)
{
    return texture2D(gm_BaseTexture,uv).r;
}

vec2 rotate(vec2 uv)
{
    uv = uv + noise(uv*0.2)*0.005;
    float rot = curlStrain;
    float sinRot=sin(rot);
    float cosRot=cos(rot);
    mat2 rotMat = mat2(cosRot,-sinRot,sinRot,cosRot);
    return uv * rotMat;
}

float fbm (vec2 uv)
{
    float rot = 1.5;
    float sinRot=sin(rot);
    float cosRot=cos(rot);
    float f = 0.0;
    float total = 0.0;
    float mul = 0.5;
    mat2 rotMat = mat2(cosRot,-sinRot,sinRot,cosRot);
 
    for(int i = 0;i < noiseOctaves;i++)
    {
        f += noise(uv+runTime*0.00015*timeScale*(1.0-mul))*mul;
        total += mul;
        uv *= 3.0;
        uv=rotate(uv);
        mul *= 0.5;
    }
    return f/total;
}

void main(void)
{
    vec2 uv = fragCoord.xy/(40000.0*cloudScale);
 
    float bright = brightness*(1.8-skyCover);
 
    float color1 = fbm(uv-0.5+runTime*0.00004*timeScale);
    float color2 = fbm(uv-0.05+runTime*0.00002*timeScale);
 
    float clouds1 = smoothstep(1.0-skyCover,min((1.0-skyCover)+softness*2.0,1.0),color1);
    float clouds2 = smoothstep(1.0-skyCover,min((1.0-skyCover)+softness,1.0),color2);
 
    float cloudsFormComb = saturate(clouds1+clouds2);
 
    vec4 skyCol = vec4(0.6,0.8,1.0,1.0);
    float cloudCol = saturate(saturate(1.0-pow(color1,1.0)*0.2)*bright);
    vec4 clouds1Color = vec4(cloudCol,cloudCol,cloudCol,1.0);
    vec4 clouds2Color = mix(clouds1Color,skyCol,0.25);
    vec4 cloudColComb = mix(clouds1Color,clouds2Color,saturate(clouds2-clouds1));
 
    gl_FragColor = mix(skyCol,cloudColComb,cloudsFormComb);
    //gl_FragColor = vec4(cloudColComb.rgb,cloudsFormComb);
}

In the following example, I would like the colors to not be weird. I just want light gray fog with transparency in between.
The blue dot represents a player object. It should be under the fog with no color change.
Fog Troubleshoot Example.png

I should also mention that I did not write this shader. I found it on the internet somewhere.
I have very minimal experience coding a shader. This could just be a matter of changing a few values.

EDIT: The room background is black by the way. So instead of that blue color, it should be black.
 
Last edited:
Top