• 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!

Shockwave Shader Issue ()

Hunter117

Member
Hey guys I am having an issue with a shockwave effect I implemented into my game using this youtube tutorial from the gaming reverend @The Reverend . I noticed one of the comments mentioned there was an issue with other objects being drawn incorrectly while the shader was active and the creator said to make a thread here and tag him. I have noticed it when I am drawing things with transparency like the godrays in this example.

Here's a gif demonstrating the problem.

Shockwave changing godrays in background

I have checked the blend modes for the object and they seem to be written correctly and reset to normal but I haven't found the cause of the issue. I'm pretty inexperienced with shaders so i'm looking for help if possible.

Here's the post draw event code incase that helps

GML:
/// @description Draw surface for shockwave

//Just draw the application surface if the list of waves is empty
//else draw the application surface distorted by the shader.

var wave_list_size = ds_list_size(list_of_waves)

if (wave_list_size <= 0)
    {draw_surface(application_surface,0,0);}
    else
        {
        //Set values
        var fx_strength = 0.05;
        var aberration = 1;
        var subimage = 0;
        
        //Create waves surface
        if (!surface_exists(srf_waves))
            {
            srf_waves = surface_create(view_w * srf_waves_scale, view_h * srf_waves_scale);
            tex_waves = surface_get_texture(srf_waves);
            }
            
        texture_set_interpolation(true);
        
        //Draw wave sprite to wave surface
        surface_set_target(srf_waves);
        draw_clear_alpha($FF7F7F,1);
        gpu_set_blendmode_ext(bm_dest_colour,bm_src_colour)
        shader_set(shd_add_normals);
        
        var w, this_wave;
        //var wave_list_size = ds_list_size(list_of_waves)
        for (w = 0; w < wave_list_size; w++)
            {
            this_wave = list_of_waves[|w];
            draw_sprite_ext(sprite,subimage,
                            (this_wave[|waveparam.xx] - __view_get( e__VW.XView, 0 )) * srf_waves_scale,
                            (this_wave[|waveparam.yy] - __view_get( e__VW.YView, 0 )) * srf_waves_scale,
                            this_wave[|waveparam.scale] * srf_waves_scale,
                            this_wave[|waveparam.scale] * srf_waves_scale,
                            0, c_white, this_wave[|waveparam.alpha]);
            }
            
        shader_reset();
        gpu_set_blendmode(bm_normal);
        surface_reset_target();
        
        //Draw application surface with waves as 2d texture;
        shader_set(shader);
            shader_set_uniform_f(u_fx_strength, fx_strength);
            shader_set_uniform_f(u_aspect, aspect);
            shader_set_uniform_f(u_aberration, aberration);
            texture_set_stage(u_tex_waves, tex_waves);
            draw_surface(application_surface, 0, 0);
        shader_reset();
        
        texture_set_interpolation(false);
        }
Many Thanks
 
Not sure what the reason for this effect is, but I'm guessing it's how you draw the god rays and how alpha values are blended. A possible fix could be this:
In the second shader where you draw the application_surface, change the last line of the fragment shader ...

... from this:
Code:
gl_FragColor    = out_col;
... to this:
Code:
gl_FragColor    = vec4(out_col.rgb, 1.0);
Is that working?
 

Hunter117

Member
Not sure what the reason for this effect is, but I'm guessing it's how you draw the god rays and how alpha values are blended. A possible fix could be this:
In the second shader where you draw the application_surface, change the last line of the fragment shader ...

... from this:
Code:
gl_FragColor    = out_col;
... to this:
Code:
gl_FragColor    = vec4(out_col.rgb, 1.0);
Is that working?

This helps thanks for the response, unfortunately there still seems to be a 1 frame flicker on the godrays seen in this gif link. So the way I am drawing the background is in my parallax object draw event. if there's any more info i can give you let me know. I really appreciate the help.

draw
GML:
if layer_exists("Godrays1") {
    var lay_id = layer_get_id("Godrays1");
    var back_id = layer_background_get_id(lay_id);
    var a = scr_wave(0.1,1,8,0);
    layer_hspeed("Godrays1",0.01 + (movedX/1.2));
    layer_background_alpha(back_id,a);
    }

if layer_exists("Godrays2") {
    var lay_id = layer_get_id("Godrays2");
    var back_id = layer_background_get_id(lay_id);
    var a = scr_wave(0.1,1,6,3);
    layer_background_alpha(back_id,a);
    }
 
So I'm guessing the god rays are reducing the alpha of the application surface when you draw them. However I'm not sure what's different between 2 frames before the wave and 1 frame before the wave. I think that's where you need to look for a real solution.

However a possible but crude fix could be not blending the alpha-channel when drawing the application surface - Im just guessing though.

i.e. turn this:
Code:
if (wave_list_size <= 0)
    {draw_surface(application_surface,0,0);}
into this:
Code:
if (wave_list_size <= 0)
{
    gpu_set_blendenable(false);
    draw_surface(application_surface,0,0);
    gpu_set_blendenable(true);
}
Then when drawing the application surface the alpha-channel should not be blended with whatever is beneath.

If that works and you can't find the real reason for that blip, you could revert the change in the fragment shaderfrom earlier and just turn off alpha blending no matter whether there's a wave or not.
 

Hunter117

Member
So I'm guessing the god rays are reducing the alpha of the application surface when you draw them. However I'm not sure what's different between 2 frames before the wave and 1 frame before the wave. I think that's where you need to look for a real solution.

However a possible but crude fix could be not blending the alpha-channel when drawing the application surface - Im just guessing though.

i.e. turn this:
Code:
if (wave_list_size <= 0)
    {draw_surface(application_surface,0,0);}
into this:
Code:
if (wave_list_size <= 0)
{
    gpu_set_blendenable(false);
    draw_surface(application_surface,0,0);
    gpu_set_blendenable(true);
}
Then when drawing the application surface the alpha-channel should not be blended with whatever is beneath.

If that works and you can't find the real reason for that blip, you could revert the change in the fragment shader from earlier and just turn off alpha blending no matter whether there's a wave or not.
Bro thanks so much for the help. That looks like it's working. Really appreciate it.
 
Top