How To Key Out Any Color Using A Shader in Godot 3

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

In Godot 2 I used the following script to key out (not display) a color from an image in the viewport and during gameplay:

uniform texture diffuse;

color alpha = tex(diffuse, UV).rgba;

if (alpha.r == 1.0 && alpha.g == 0.0 && alpha.b == 1.0) {
    alpha.a=0.0;
}

COLOR = alpha;

In Godot 3, this doesn’t work. Does anyone know how I can revise this code for compatibility with Godot 3+?

By the way, I have reasons why I am not using transparency which I describe here. Thanks in advance for the help.

:bust_in_silhouette: Reply From: SIsilicon

Shaders in Godot 3 have an overhaul.

As of this version, you must:

  1. define what kind of shader it is with shader_type. Either spatial, canvas_itemor particles. I’m assuming your working in 2D so you’ll want canvas_item.
    shader_type canvas_item;
  1. define uniform textures with sampler2D instead of texture.
    uniform sampler2D diffuse; // replaces your line 1
  1. use vec4 instead of color.

  2. use texture instead of tex.

  3. put your main code in a shader function. Either vertex, fragment and/or light depending on what aspect of the mesh/Sprite your working with. Since your working with pixels’ colours, you need to put that code of yours in a fragment shader.
    Note you can use all of them in one shader if you need a combination of them.

I can go on with the changes, but these are the ones needed to convert your shader into a Godot 3 compatible one.

shader_type canvas_item;

uniform sampler2D diffuse;

void fragment() {
    vec4 alpha = texture(diffuse, UV);

    if(alpha.r == 1.0 && alpha.g == 0.0 && alpha.b == 1.0) {
        alpha.a = 0.0;
    }

    COLOR = alpha;
}

Visit here to learn more about the new shading language.

Thanks for your thorough response. I finally got a chance to try this out and It does not seem to work. I created a “New Shader Material” on the TextureRect I want to affect and I don’t see anything happening. I even tried directly assigning the values to alpha.r, alpha.g, etc and I saw no change. Am I missing something?

davidpgil | 2018-11-18 16:59

It works for me. Maybe you are missing something.

SIsilicon | 2018-11-19 16:36

I tried it again a bit today and I realized that I applied the shader to the wrong node so I was not seeing anything. Now, the shader is connected to the correct node, but the result is just turning the whole texture some shade of white. I mean to remove only the hot pink color and leave the rest of the colors visible - like a green-screen effect.

Here is the image I am trying to key-out the hot pink:
Title Screen Without Keying

With the code you gave me I am seeing this:
Title Screen With Your Code

UPDATE:
I figured out how to fix my issue by using hint_color and fiddling with the Godot UI. I shared the results here

davidpgil | 2018-11-25 02:57

:bust_in_silhouette: Reply From: MysteryGM

I am just shortening @SIsilicon’s answer. For other people who find this question.

A chroma key shader in Godot looks like this:

shader_type canvas_item;

//Get texture and a key that we want as transparent
uniform sampler2D Diffuse;
uniform vec4 ChromaKey : hint_color;

void fragment(){
	//The color value is the sampled pixel color
	COLOR = texture(Diffuse, UV);

	//If the color is the same as the chroma key, make it transparent.
	if (COLOR == ChromaKey)
    {
		COLOR.a = 0.0;
	}
}

Try it with the Godot Icon, it’s color number is # 355570

Thanks for the extra perspective on this one. I am trying to get your version to work as well, and I am having trouble with where to put the color value. I also don’t understand the syntax of line 5, “uniform vec4 ChromaKey : hint_color;” … Whats a “hint color”?

davidpgil | 2018-11-18 19:38

As its name implies it pretty much tells Godot that the kind of uniform you’re passing in is a colour. Making it not only a lot easier to edit than a plane attribute, but it also has automatic srgb conversion (I think).

SIsilicon | 2018-11-19 16:23

I can’t get this code to work for me.

UPDATE: I got this working by fiddling with the hint_color UI. Your solution was correct. I just needed more information about how to configure it in the UI.

I shared the results here

davidpgil | 2018-11-25 03:06