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

Shaders [Solved] Blur shader does not blur translucent objects correctly

A

alex19735

Guest
Hello, I am trying to blur a specific area in the game window that basically blurs everything underneath it. I have managed to make it work using a separate surface for the blur, however it seems it does not blur translucent objects correctly. I have a shadow system set up with a separate surface for it, and basically the entire surface has the alpha set to 0.5.


This is the blur without the shadows. Works fine! (You can see it in the top left corner)



Here is the blur with the shadows. As you can see, the shadows not only don't blur, but they make everything around them not blur as well.



And here is the blur with the shadow surface set to alpha 1, working fine.

Here is the code to the shader:
Code:
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform vec3 size;//width,height,radius

const int Quality = 8;
const int Directions = 16;
const float Pi = 6.28318530718;//pi * 2

void main()
{
    vec2 radius = size.z/size.xy;
    vec4 Color = texture2D( gm_BaseTexture, v_vTexcoord);
    for( float d=0.0;d<Pi;d+=Pi/float(Directions) )
    {
        for( float i=1.0/float(Quality);i<=1.0;i+=1.0/float(Quality) )
        {
                Color += texture2D( gm_BaseTexture, v_vTexcoord+vec2(cos(d),sin(d))*radius*i);
        }
    }
    Color /= float(Quality)*float(Directions)+1.0;
    gl_FragColor =  Color *  v_vColour;
}
I am sorry if this has an obvious solution, I have only started using Gamemaker recently and don't really know it that well.

Thank you in advance.
 

Attachments

Ido-f

Member
It sounds like the problem is with the shadows' surface, so you might want to post yout code for it.
My guess is that you're drawing the shadow surface, unblurred, on top of everything else.
Another thing to consider is that using transparency in a surface makes that point in the surface transparent - even if it was cleared with an alpha 1 color beforehand.
Here's a blog post on the problem and its solutions - https://www.yoyogames.com/blog/60/alpha-and-surfaces
I find that the best solution is to use color_writeenable(true, true, true, false) before drawing anything to the surface and color_writeenable(true, true, true, true) when you're done drawing to it.
It will blend the transparent colors correctly but will keep the resulting surface's alpha unaffected.
 
A

alex19735

Guest
Thanks for the reply! I've read the post you linked, but nothing from there seemed to work. Using
gpu_set_colorwriteenable causes any surface I put it on to disappear entirely, but maybe I'm using it wrong.

I've also searched through some other similar posts, but nothing I've tried seems to work. Thank you in advance.
 
Last edited by a moderator:
A

alex19735

Guest
I managed to fix the problem, as I said I wasn't using gpu_set_colorwriteenable right, setting it to false right before drawing the surface itself and then setting it back fixed it. Thanks for the help!
 

Ido-f

Member
Yea, I was about to suggest that. Before drawing the shadows surface, right? That's interesting, because I think it means that the alpha of it was being written into the application surface (which is peculiar because I've read that the application surface has no alpha channel), then copied into the blur surface, which made it blend again with the application surface again when drawn, resulting in an only half blurred image.

btw, two points regarding your code:
Code:
surface_free(shadowSurface);
This is redundant. You should free the surface in a cleanup event, not every draw event.
Code:
with (objShadowsStaticParent){
       repeat (wallCount){
           draw_sprite(sprWallShadow,0,x-viewX,y-viewY);
       }
   }
"with" already goes through each instance, if I'm not mistaken you are drawing each wall's sprite multiple times on itself over and over again there with the repeat loop.
 
A

alex19735

Guest
Thanks for your suggestion! Now that I've removed that repeat loop the game pretty much runs twice as fast. As I said I'm just starting to learn Gamemaker, so I guess things like this are bound to happen.
That surface_free() function was there because I had completely run out of ideas as to how to fix the issue, so I just tried everything I could.
Once again, thanks for your help!
 
Top