1. Hey! Guest! The 34th GMC Jam will take place between August 22nd, 12:00 UTC (Thursday noon) and August 26th, 12:00 UTC (Monday noon). Why not join in! Click here to find out more!
    Dismiss Notice

Fog environment

Discussion in 'Programming' started by JeanSwamp, May 9, 2019.

  1. JeanSwamp

    JeanSwamp Member

    Joined:
    Jan 11, 2018
    Posts:
    118
    Hello there,

    Been digging now and then for possible ways to create environment mood to the levels. I think Dead Cells is a good example on this to pixel art games.

    What's a good approach to create fog into a 2d platformer in a way that can be used for different feelings, for example some water-ish atmosphere for rain, dust for a desert, and snow-ish for some sort of ice-level.

    Thanks in advance!
     
  2. trentallain

    trentallain Member

    Joined:
    Aug 6, 2016
    Posts:
    521
    You could draw a slightly alpha coloured rectangle to a surface in the colour you like to represent the mood, and then subtract a circle around the player from the surface to make it easier to see around you.

    For dust and fog, you could create some large sprites from them that just hover around at the edges of the screen. You can use all of the above in addition to some rain/snow particle effects too
     
  3. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    1,867
    I've made mist with tileable sprite that was based on photoshop cloud filter plus some motion blur horizontally and turning the color gradient into alpha. (I forget how I tiled it, as PS clouds normally don't.) I recall I had it drawn twice in GMS, first pass getting an offset that moved right, the second getting an offset that moved left. I ended up with that after studying how some old 2D JRPGs drew their mist. For sand- and snowstorms, I suppose you can draw just one pass and make it move pretty fast and tint it with sprite_draw_ext, and add some single pixel-sized particles for extra effect.
     
  4. JeanSwamp

    JeanSwamp Member

    Joined:
    Jan 11, 2018
    Posts:
    118
    The thing is drawing a static sprite will feel a bit blend. I'm looking for something more in this matter:

    [​IMG]
     
  5. pruto

    pruto Member

    Joined:
    May 10, 2019
    Posts:
    5
    1. Put like 100 of this type of sprite [​IMG] (maybe irregular shape with angular speed is better) on a surface and let them move randomly. Or you want the fog move slowly towards left, you can let them move left with random speed and drag them back to the right when they are out of the screen.
    2. Use shader to enhance visual effect. For example:
    Aggregating alpha 0-0.2 to 0.1, 0.2-0.4 to 0.3 and so on to generate fog layer effect
    Set a random value from 0-4, and if texture pixel position mod 5 equals that value, then increase this pixel's alpha. This can generate dither effect. Or choose 1 pixel from 3x3 pixels to do that, whatever you want
    Get those coords of light source, enhance the color and alpha of fog near them
     
  6. teamrocketboyz

    teamrocketboyz Member

    Joined:
    Jul 27, 2017
    Posts:
    275
    i thought i would give this fog thing a go myself as i like to try create other peoples problems aswell as my own as it helps me to learn different aspects im yet to reach myself. i quite liked the sound of this idea and i managed to create a very small basic fog demo. its very demanding on the fps but an effect none the less.

     
  7. JeanSwamp

    JeanSwamp Member

    Joined:
    Jan 11, 2018
    Posts:
    118
    Yeah I really need something less demanding than drawing tons of sprites.
     
  8. flyingsaucerinvasion

    flyingsaucerinvasion Member

    Joined:
    Jun 20, 2016
    Posts:
    2,088
    Here's something you could try, if you are okay using a shader.

    Basically you just draw a sprite covering the areas where you want fog. And you use the shader to sample the fog texture at multiple positions that change over time. You can multiply together the resultant samples to determine the fog's opacity.

    Make sure you turn texture repeating on for this texture. And make the fog sprite on its own texture page.

    Example fog texture sprite:
    upload_2019-5-14_11-24-3.png

    See spoiler for implementation details:
    If your fog sprite follows the view, then you don't want the texture to appear to move along with the camera. One relatively easy way to do that is to set the texture coordinates based on the current vertex position. In the vertex shader:
    Code:
    attribute vec3 in_Position;
    varying vec2 v_vTexcoord;
    void main() {
        gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * vec4(in_Position,1.0);
        v_vTexcoord = in_Position.xy / 512.0;
    }
    
    Fragment shader:
    Code:
        varying vec2 v_vTexcoord;
        uniform float time;
        const vec3 fog_color = vec3( 1.0, 1.0, 1.0);
        //velocity vectors
        const vec2 A_dir = vec2(0.76604,0.64279);
        const vec2 B_dir = vec2(0.58207,-0.48841);
        const vec2 C_dir = vec2(0.54253,0.19747);
        const vec2 D_dir = vec2(0.41224,-0.15004);
        const vec2 E_dir = vec2(0.33333,0.00000);
        void main() {
                                                                                //scale
            float A = texture2D( gm_BaseTexture, (v_vTexcoord + A_dir * time) * 1.000000000).r;
            float B = texture2D( gm_BaseTexture, (v_vTexcoord + B_dir * time) * 0.759835686).r;
            float C = texture2D( gm_BaseTexture, (v_vTexcoord + C_dir * time) * 0.577350269).r;
            float D = texture2D( gm_BaseTexture, (v_vTexcoord + D_dir * time) * 0.438691338).r;
            float E = texture2D( gm_BaseTexture, (v_vTexcoord + E_dir * time) * 0.333333333).r;
     
            //changes how much each component affects the fog density.
            E = pow(max(0.0,E),1.000000000); //affects most
            D = pow(max(0.0,D),0.759835686);
            C = pow(max(0.0,C),0.577350269);
            B = pow(max(0.0,B),0.438691338);
            A = pow(max(0.0,A),0.333333333); //affects least
     
            float fog = A*B*C*D*E;
     
            //At this point there are any number of operations you can perform on "float fog"
            //in order to increase or reduce the level of fog
            //or to make the fog appear more patchy or more uniform
            //For example, to make the fog much thinner, you could multiply "fog" by itself a few times:
            //fog = fog * fog * fog;
     
            gl_FragColor = vec4(fog_color,fog);
        }
    
    An example of one way to draw the fog:
    Code:
    shader_set(sh_fog);
    shader_set_uniform_f(shader_get_uniform(sh_fog,"time"),current_time/20000);  //note: probably should use your own time variable instead of current_time.
    draw_sprite_stretched(spr_fog,0,view_xview,view_yview,view_wview,view_hview);  //if using GMS2, subsitute view_* with GMS2 equivalents.
    shader_reset();
    
    If you have trouble fitting a fog sprite to a rotating view, let me know, because there are easy ways to overcome that problem.
     
    Last edited: May 14, 2019
  9. pruto

    pruto Member

    Joined:
    May 10, 2019
    Posts:
    5
    I tried my method myself, and found it not bad. The fps of an empty project on my mac is 7000 while my fog demo is 4000-5000. And I found water effect appears when I scale the fog sprite.
    I draw 120 of this sprite with different speed and scale on a surface, and applied my shader on that surface to generate fog layer effect. Might be better after adjusting some vars.


    and it can be better in performance with perlin-noise picture. Good idea, i'll give it a try. Thanks to flyingsaucerinvasion
     
    Last edited by a moderator: May 20, 2019
  10. pruto

    pruto Member

    Joined:
    May 10, 2019
    Posts:
    5
    Here is the implementation of flyingsaucerinvasion's idea with the perlin noise sprite stretched to 512x512. Fps is 5000-6000 on my mac and the effect is cool.

    I have been working on my game for 5 months, and fog & water effects await to be done. This is really an enlightenment for me.
     
  11. flyingsaucerinvasion

    flyingsaucerinvasion Member

    Joined:
    Jun 20, 2016
    Posts:
    2,088
    I've found that if you take the basic random noise premise like we've been talking about in the least few posts, and adjust it in the following way, you can get some pretty cool vortex looking results. What you do is you compute a random value twice. Compute it once, and then feed it in as a random offset for a second value. The consequence is your uv positition is stretched and squished in ways that vary over time, which sort of looks like the random vortices in fog. The downside is it is rather difficult to control. It takes a lot of tweaking.
     
  12. teamrocketboyz

    teamrocketboyz Member

    Joined:
    Jul 27, 2017
    Posts:
    275
    man what an amazing outcome. this is such a nice thread a real eye opener.
     
  13. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    1,867
    Ooh perlin noise. What's the base size since you say stretched? I recall reading on, and playing around with some perlin shaders one time I was looking for a cloud-ish effect, and they seemed pretty heavy on the GPU. Not sure how optimized the stuff was, back then I didn't really know much about shaders so it was for the most part copy-paste testing.
     
  14. teamrocketboyz

    teamrocketboyz Member

    Joined:
    Jul 27, 2017
    Posts:
    275
    Im still playing around with this little idea, i have managed to create a thick fog that moves when touched. it could look nice on a cloud based platformer. the fog is thick but thats a choice i made and could be made as thick or thin as desired.

     
  15. pruto

    pruto Member

    Joined:
    May 10, 2019
    Posts:
    5
    I stretched that noise picture from 100x100 to 512x512 for better use in shader.
    Don't try to generate perlin noise with algorithm in gamemaker, it's a disaster cause gamemaker performs poor in calculating. Shader is good at handling pixel. Assume there are several noise sprites with different speed on the stage and use shader to calculate every pixel color based on the pixel color of those overlayed noise sprite in that position. Then a mixed foglike view is generated. Coding in the shader, you can pretend there are several sprites and calculate the pixel color of them with 'time' variable and their speed, while only call draw_sprite function once. That's how that fog shader works
     
  16. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    1,867
    Oh ok, I was getting the idea that the noise was generated on the fly. The stuff I tested had the perlin noise generated realtime in a shader, and that didn't seem very powerful either.
     

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