+1 vote

Hello. I have a sprite whit a png texture and I want to make transparent the black areas of this image (I know this can be done modifying the image with other programs like photoshop, but I would have to do that many times and I think is better to solve this using code).
I’m trying to use the solution found in https://godotengine.org/qa/18639/how-can-i-set-any-single-color-to-be-transparent

shader_type canvas_item;
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;
}
COLOR=col;

The problem is that Godot does not recognize “diffuse” as a variable (I’m getting error(3): Expected datatype.) I’m trying to understand the shading language, but I still don’t get it, I would really appreciate if you can help me understand how this works

in Engine by (129 points)

2 Answers

+2 votes
Best answer

Is that the entire shader? Because if so the problem is that you forgot the fragment function, vec4 instead of color,texture instead of tex and sampler2D instead of texture:

shader_type canvas_item;
uniform sampler2D diffuse;

void fragment(){
vec4 col = texture(diffuse,UV).rgba;
if (col.r==1.0 && col.g==0.0 && col.b==1.0) {
    col.a=0.0;
}
COLOR=col;
}

EDIT:
I edited because i saw other errors later.

by (200 points)
selected by
  1. You can omit the .rgba in the line where you sample the texture, since you're storing it in a vec4 anyway.
  2. The conditional inside the if can be replaced with col.rgb == vec3(1,0,0).

Just thought I'd help shorten the code.

Thanks!!! that works perfect, but I realized the condition "if" was too abrupt for me and I need something that works with a grayscale. The following make a smooth transition to transparency

shader_type canvas_item;
uniform float max_col_b = 0.22;
float line(float col_b){
    return (1.0/max_col_b)*col_b;
}
void fragment(){
    vec4 col = texture(TEXTURE,UV).rgba;
    if (col.r<=24.0 && col.g<=24.0 &&  col.b <= max_col_b) {
        col.a = line(col.b);
    }
    COLOR=col;
}
0 votes

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.