0 votes


I have some textures I would like to apply a grey effect eventually.
To explain myself better, I want to apply this effect to some textures when disabling or enabling them.

There are a lot of different textures and I would like to accomplish this by code (if possible) instead of creating a "disabled_texture".

Any ideas? Someone suggested shaders but I don't know how they work and the documentation I found does not help me at all.


in Engine by (86 points)

2 Answers

+1 vote
Best answer
  1. Create a new CanvasItemMaterial:

  2. Edit the new CanvasItemMaterial:

  3. Create a new CanvasItemShader:

  4. Use this code as Fragment Shader:
    COLOR.rgb = vec3(dot(COLOR.rgb, vec3(0.299, 0.587, 0.114)));
    Here you'll find an explanation of the calculation above.

Enabling/Disabling grayscaling at runtime

You can extend your shader code to have an uniform variable to control whether applying the grayscale filter or not. This would look like this:

uniform bool grayscale = false;

if (grayscale) {
    COLOR.rgb = vec3(dot(COLOR.rgb, vec3(0.299, 0.587, 0.114)));

After changing your shader code to the above, you should have a new option in your CanvasItemMaterial:

by (698 points)
selected by

Better solution than mine! Colours don't have the same gamma contribution and this really makes use of it (for example, green is brighter than blue on a CRT screen)

Small warning though: use if with care in a shader, for some graphic cards it means compiling as many binaries as combinations since GPUs work differently than CPUs.

Thank you for your answer! Really great effect, what I was searching for!

Is this process possible to be made in GDScript? I would like to create the shader and attach it to all TextureFrames I have.

I would like to know too, is this the only way to get that effect? I expected something like "TextureFrame.set_color("grey")", because as far as I know, shaders are code that are always running and I'm afraid about that.

Grey is not a color, it is the absence of color (or the presence of all of them, depends on the brightness :p), so you cannot really do set_color(grey).

When you do set_color you'll apply a tint over the base texture, but you cannot remove colors this way. You could just use that if your texture is monochrome, but otherwise you need a shader.

The GPU executes shaders tens of thousands times faster than GDScript, and this shader is so simple it might even be faster than the default one. Don't worry too much about that :)

This shader is nothing for a GPU...
So, the optimal way would be writing that shader, save the shader (NOT the material) as .shd (Go into shader edtiting mode and click the save icon at the upper left hand of the inspector). Then set the disabled-property with GDScript

I rewrote this shader in VIsualShader for Godot 3.1 over on my blog. Thanks for making such a simple shader that I could use as a base for learning about VisualShader!

Well, this doesn't work with godot 3.
I messaged it into this :

shader_type canvas_item;
uniform bool grayscale = false;

void fragment() {
    if (grayscale) {
        COLOR.rgb = vec3(dot(COLOR.rgb, vec3(0.299, 0.587, 0.114)));

but all that does is gives me a completely grey square.

+1 vote

Here is a simple fragment shader that will turn your sprite into greyscale:

// Get the color from the texture
vec4 col = tex(TEXTURE,UV);

// Compute greyscale color (mean of red, green and blue)
float grey = (col.r + col.g + col.b) * 0.333;

// Apply greyscale color (same for red, green and blue, then we keep the same alpha)
COLOR = vec4(grey, grey, grey, col.a);

To apply this shader, go to the Material property of your sprite (or any CanvasItem), create a new material, and assign it a new shader. Then you'll be able to write the fragment shader inside :)

by (27,897 points)

This results in grayscale, however it is not as accurate to human vision as the formula in my answer. See here ;-)

Thank you Zylann! ;)

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.