+3 votes

I have an image that has no alpha channel with a logo in the middle and the rest of the image is hot pink (red 255, green 255, blue 0). I want to make that color transparent in Godots viewport and when the game is run. How do I do that?

I know I can just save a PNG with alpha transparency, but I have some reasons I do not want to do this. I want to to "key out" or "chroma key" the hot pink color so it is not visible at all.

If this needs to be done with a script, please help me find what I need to look at in order to do this.

Thanks in advance for any help.

in Engine by (88 points)
recategorized by

I know I can just save a PNG with alpha transparency, but I have some reasons I do not want to do this.

Using alpha transparency in PNGs is a better idea – image editing in a game engine is rarely a smart thing to do, and Godot does not have functionality to display a single color value as transparency.

This can be done automagically using ImageMagick. For example, you could use this ImageMagick command, looping over PNG files with a constant color as transparency key (here, it's cyan):

mogrify -transparent "rgb(0, 255, 255)" image.png

Note that this will overwrite the original files, use convert instead of mogrify to be able to specify a destination file name.

Thank you for your thoughtful response.

My hope was to take advantage of indexed color graphics. I have worked in creating gameboy and nintendo ds games in the past and I want to work with images in a very similar way where I could play with color indexes of a small group of colors to create certain visual effects. I know these days people don't use indexed color graphics except for animated gifs, but I want to retain this "feel" for my project.

Again, I appreciate your response because it grants me more information to play with with. Also, imagemagick is awesome! tip of the hat to you.

Reviving this thread regarding Godot 3. The below solution works in Godot 2 but now I want to do this in Godot 3. How can I do this? If I should start a new thread, please let me know.

Anyone know how to do this in Godot 3?

2 Answers

+3 votes
Best answer

You could write a shader/create a shader material which sets the alpha value in diffuse_alpha dependent on the color value.

http://docs.godotengine.org/en/stable/learning/features/shading/shading_language.html

This one also touches the alpha topic:
http://docs.godotengine.org/en/stable/learning/features/shading/shading_language.html

Or you simply import the png texture and use the imported *.tex file if you just don't like the png format for some reason (patents, licenses, local regulations i.d.k.)

by (3,252 points)
selected by

Thanks for your reply!

I am just starting with Godot and didn't know about shaders in Godot so I think I now have my work cut out for me with the links you provided. Though, both links (at the moment) are the same? Thankfully I am familiar with C.

I'm not aware of *.tex files so I think I need to investigate that as well. Can the tex file be used to manipulate the the format of the image? For example, can I take a high-res image and make it 8 colors and indexed, for example?

I'm experimenting with using only FOSS tools for creating my game. I wasn't aware that PNG had any issues with free software/ patents.

Thanks for your info -- Threw a lot of homework on my lap ^_^"

==== UPDATE 1
So, I created this script and its not working. I am still researching. Im about to turn in for the night (im in asia), but I thought I would post my non-working shader in case you had anything to add/say.

// specify the color to be transparent which is r255, g0, b255 or what I like to call hot pink 
color alpha_color = vec4(1.0, 0.0, 1.0, 1.0);
color texscreen sample_pixel = vec2(0, 0);

// if the pixel matches hotpink, make it transparent
if(sample_pixel == alpha_color)
{
    COLOR.a = 0.0;
}

First, sorry about the missing link. Obviously a Copy & Paste error.
The missing link is (i think):
https://godotengine.org/qa/13010/alpha-masking-a-3d-object-using-materialshader-language?show=13010#q13010

About patents:
PNG basically has no (known) patent problems:
http://www.libpng.org/pub/png/pngfaq.html#patents

I did just not know which reasons led you to avoid the PNG-format.
This is because PNG can as well works with a (arbitrary) limited amount of colors and either alpha-channel transparency or single-color transparency.

The *.tex advice was just a way to avoid the png-format if you (for unknown reasons on my side) want to avoid PNG because of the format itself.

My advice is still to simply use the png-format. But if you want to experiment with shaders. Here's a material shader (fragment):

uniform texture diffuse;
color col = tex(diffuse,UV).rgba;
if (col.r==1.0 && col.g==0.0 && col.b==1.0) {
    col.a=0.0;
}
DIFFUSE_ALPHA=col;

You might have to switch other shaders off to have this working fully. I.e. switch mipmap & filter flags off for the diffuse texture.
I tested this in 3D. Might be slightly different for 2D.

That worked! With a small tweak. I needed to change "DIFFUSE_ALPHA=col;" to "COLOR=col;" ... Many thanks!

Thanks for the corrected link about shaders in Godot.

... I'm fine with PNG. it's a great format. I am hoping there is some benefit to using indexed PNGs instead of PNGs with an alpha channel down the road, however. I am in a very early investigative/learning phase with my project. At the moment I am simply trying to replicate my workflow for when I was working on Gameboy games. Back then we used PNGs :)

OK. You basically gave me all I need. You have my regards, sir!

0 votes

Per answer to https://godotengine.org/qa/38274/set-single-color-to-transparent-using-shaders?state=edit-83461

I had very similar sounding reasons for not using PNG - trying to support 'legacy' data files that include bmp and other supporting data files that specify the transparent color for the texture etc.


I managed to achieve something along these lines through a custom spatial shader that sets 'discard' if the underlying texture color matches a certain value. In my situation, I am generating meshes and applying textures at runtime from legacy formats (including bmp) which have alpha color specified in some of the supporting data files.

Example shader code and (C#) script to achieve this is below - note it's somewhat hacked together to assume that the "transparent" color is bright blue (rgb 0,0,255).

C# script to assign the shader

ImageTexture tex = new ImageTexture();
Error e = tex.Load("path/to/texture.bmp");
ShaderMaterial sm1 = new ShaderMaterial();

sm1.Shader = ResourceLoader.Load<Shader>("res://simple_trans_tex.shader");
sm1.SetShaderParam("day_texture", tex);

Shader (saved in project as simpletranstex.shader)

shader_type spatial; 
render_mode cull_disabled;

uniform sampler2D day_texture : hint_albedo;

void fragment() {
    vec3 day_tex_color = texture(day_texture, UV ).rgb;

    // filter out transparent color
    float blue = 255f / 255f;

    ALBEDO = day_tex_color;

    // discard pixels (transparency) when 8 bit blue = 255
    if (day_tex_color.r==0.0 && day_tex_color.g==0.0 && day_tex_color.b==1.0) {   
       discard = true;
    }
}
by (18 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.