2D texture Mask Shader to simply mask part of a Sprite in Godot 3.0

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By gp1

Hello everyone.

Let’s say we have this sprite Sprite and this mask Mask and we want to get this End result

I’m a beginner in Shaders but from what I gathered, if I’m right, I need a shader that just mixes between the image alpha and the alpha of the sprite.

After days of googling, any help would be really appreciated!

:bust_in_silhouette: Reply From: SIsilicon

You know, it doesn’t hurt to visit the Godot docs to learn about Godot shaders. Other than that I can understand you being a beginner.

To start working with shaders, you need a ShaderMaterial to use… You know what? This link here should have what I’m about to say and more. After making your ShaderMaterial along with a shader(reference link before), start editing the shader and type this in.

shader_type canvas_item;

uniform sampler2D mask_texture;

void fragment() {
    vec4 colour = texture(TEXTURE, UV);
    colour.a *= texture(mask_texture, UV).a;
    
    COLOR = colour;
}

Now I wouldn’t be helping you if I didn’t explain this code.

The first line tells Godot what kind of shader this is and what it’s used for. In this case it’s used on a Sprite, an extension of CanvasItem.

The line with uniform allows you to pass a value to the shader of a certain type specified by the keyword that follows. In this case the second keyword is sampler2D, which means we can pass a texture to the shader through this uniform.

the next thing that follows is the definition of the fragment function. This function gets called for every pixel, so it’s pretty much the equivalent of glsl’s fragment shader’s main function. Ignore the void keyword for now.

The next two lines performs the algorithm needed to mask a texture.
By first sampling the colour at the current pixel, then multiplying the alpha of that sample by the alpha of the mask_texture, we effectively mask away the original texture at those pixels.

We finally pass this value to COLOR, and Godot does the rest from there.

I suggest you read more about the shading language though. That’s just the tip of the iceberg.

Thank you for your reply.
Game programming in general is very new to me and I do appreciate your time and effort.
When I paste the code in the Shader editor I get the following error:
Error
but when I use the following two lines, it works:

COLOR = texture(TEXTURE, UV);
COLOR.a = texture(mask_texture, UV).a;

gp1 | 2018-11-23 01:54

Oh yeah whoops. I forgot two extra important characters on the 7th line.

// Fixed!
colour.a *= texture(mask_texture, UV).a;

Correcting answer.

SIsilicon | 2018-11-23 03:03

:bust_in_silhouette: Reply From: Raheel

Adding another answer to this since this is the first post that appears when searching for a 2D UI Mask.

Godot has a Light2D CanvasItem that has a mask mode. The Godot Asset Library also has an example project that demos it.