GMS 2 Dynamic Fog

Discussion in 'Programming' started by Gamerev147, Jun 11, 2019.

Tags:
  1. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    435
    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!
     
  2. IndianaBones

    IndianaBones Member

    Joined:
    Jul 5, 2016
    Posts:
    2,069
    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.
     
  3. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    1,757
    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).
     
  4. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    435
    @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: Jun 13, 2019 at 2:52 AM
  5. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    435

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice