Legacy GM Making transparent areas opaque

kamiyasi

Member
I'm using a mask sprite in combination with bm_subtract to cut a hole in my surface, allowing the background to show through. The only problem is, for whatever reason, everything drawn that has a slight transparency is also showing the background through it, even when I use draw_enable_alphablend(false)
What I could use is something like the opposite of what draw_set_alpha_test(true) does.
upload_2018-3-8_14-27-51.png
As you can see here, the blue background is showing through everything on the surface that has a slight transparency to it, even though I'm using draw_set_alphablend(false)



Full code:
Code:
{
    if ( global.paused==1 || (obj_player.life <= 0)) && ( scr_nottitle() )
    {
        d3d_set_lighting(false);
       
        if !surface_exists(foresurf)
        {
            ///rebuild surface
            foresurf = surface_create(2560,1440);
            surface_set_target(foresurf);
            draw_clear_alpha(c_black, 1);
            surface_reset_target();
        }
        ////draw greyscale overlay
           
        surface_set_target(foresurf);
        draw_clear(c_black);
       
        shader_set(shd_greyscale);
           
        shader_set_uniform_f(uni_time, 0);
        shader_set_uniform_f(uni_mouse_pos, 0, 0);
        shader_set_uniform_f(uni_resolution, 2560, 1440);
        shader_set_uniform_f(uni_greyscale_fade, (lfade / 100));
       
        draw_enable_alphablend(false);
        draw_surface_stretched(application_surface,-1,-1,view_wview[0]+1,view_hview[0]+1);
        draw_enable_alphablend(true);
       
        shader_reset();   
    }

    if ((obj_player.life <= 0)) && ( scr_nottitle() )
    {     
   
        lfade = min(lfade+(0.25*deltaspeed),100);                   
       
       
        ///game over message cutout
       
        draw_set_blend_mode(bm_subtract);
       
        draw_set_alpha( (lfade / 110) + 0.3 );
        draw_background(bck_go1,580,604);
        draw_set_alpha(1);
       
        draw_set_blend_mode(bm_normal);
       
       
        surface_reset_target();
       
        draw_background_stretched(bck_go3,view_xview[0],view_yview[0],2560,1440);       
   
        draw_set_alpha(1);
        var csc = merge_color(c_white,c_black,clamp(0, (lfade / 110) - 0.3, 0.9) );
       
       
        draw_surface_ext(foresurf,view_xview[0],view_yview[0],1,1,0,csc,1);
       
        ///draw game over message
        draw_set_alpha( (lfade / 110) + 0.3 );
        draw_background(bck_go2,view_xview[0]+580,view_yview[0]+604);
        draw_set_alpha(1);
       
    }

}
 
K

Khanon

Guest
Hi, i will be able to respond to yours questions ... (It's about how works alpha channel (or opacity channel) and maskes.)

As you may know, when you apply a mask, you take a sprite and overlapping it over another sprite
(it can be background, foreground, etc.). Then, the sprite on the top (the mask) will serve for applying a function (cf. mathematical formula),
that's what you do when you call [bm_subtract] : it works as a filter, because it is a filter. :3
But this function (as all mask-filters) is sustainable only on white to black image (for the computation of the function),
that's why maskes are always black and white images.

That's generally, the common rule ... for an early and easy comprehension. But, it's not the complete truth about it.

You have to know how works opacity. In the (computer-)color domain, you have blue / green / red channels and an alpha channel
as the 4th one. Each channel works on a 255 intensity base. In clear, for the blue channel, there are 255 substeps for going to blue 0% to blue 100%.
Same goes for the alpha channel.

In your case, your white and black mask will works perfectly only if it is not overlapping a sprite with opacity (because, it's already an applied filter).
(i take the hypothesis the black on the mask is the seeing-throught, because i hasn't check it)
White > not seeing-throught, Black > seeing-throught. It works binary like (0-1). But when the function drops on a reduced opacity pixel :
it's not 0% neither 100% transparency, and the mask works on a 0% / 100% base. So the function has to interpret and make a choice
(considering it as a 0 or a 1 ?). Hopefully for the user, it's considered as a 100% transparency zone by the mask (making it easier
to see the problem).
Now that the problem is understood, how to bypass it ?
First, you have to know than maskes are white and black, you could say they are "bichromic expression" (or monochromatic if you consider white (or black) as null).
But it's wrong ! Maskes are not reserved on a bichrome space, maskes work on a grayscale space. You have the white, the black ...
and all of the 254 grays substeps inbetween ... for nuancing the "seeing-through".

So, if you have a sprite with 20% opacity (so 80% transparency), your filter-mask will need a 80% black appliance
(at the exact same location of yours pixels concerned).
Hope, it will serve you in your project.

ps : i take the principe than your function works with a grayscale mask, it can happens than some filter
on others softwares may accept bichromatic mask only (it depends of the software architecture and the function formulation).
 
Last edited by a moderator:
Top