+1 vote

I'm writing a simple shader that changes a single color based on interpolation. It works in-editor but not at runtime and I'm not sure why.
https://cdn.discordapp.com/attachments/408555922349359105/658885807326887966/shad.mp4
Even if I am mistaken about how editor changes for shaders work at runtime, I made an animation using an AnimationPlayer that modifies the interpolation field at runtime as well with no noticeable changes, and I know I did that right because it works in-editor as well.

I've only found a couple really old issues for Godot 2.x that were similar, and the solutions either didn't seem applicable (largely due to 2.0 deprecation) or I didn't quite understand how I could apply it to my particular case.

I'm sure I'm missing something minuscule based on that nobody seems to have this issue but any help sorting this out would be appreciated.

Edit: my shader code for reference:

shader_type canvas_item;

uniform float eye_cutoff : hint_range(0.0, 1.0);
uniform vec4 curr_eye_color : hint_color;

vec4 changeEyes(vec4 curr_color)
{
    if(curr_eye_color == curr_color)
    {
        float r = 12.0/255.0;
        float g = 123.0/255.0;
        float b = 30.0/255.0;

        float r2 = 90.0/255.0;
        float g2 = 145.0/255.0;
        float b2 = 255.0/255.0;

        float r_int = r * (1.0 - eye_cutoff) + r2 * eye_cutoff;
        float g_int = g * (1.0 - eye_cutoff) + g2 * eye_cutoff;
        float b_int = b * (1.0 - eye_cutoff) + b2 * eye_cutoff;

        return vec4(r_int,g_int,b_int,1);
    }
    else
        return curr_color;
}

void fragment() {
    vec4 curr_color = texture(TEXTURE,UV); // Get current color of pixel

    COLOR = changeEyes(curr_color);
}
in Engine by (53 points)

What are you talking about?

I’m not sure how to elucidate further. The colors I’m trying to switch are the eyes if that wasn’t clear. I show how it’s working in the linked video.

1 Answer

+1 vote
Best answer

Changing if(curr_eye_color == curr_color) to if (round (curr_eye_color) == round (curr_color)) works for me, but of course I lose color presicion. It seems that the problem is in the selection of the color of the hint_color or that ingame the color changes slightly and no longer detects them as equals. I comment if I find a better way to solve it.

by (2,060 points)
selected by

How very strange. I'm using the exact hex value for the hinted color. I'll keep messing with it too in the meanwhile.

adding this function:

vec4 trunc_vec(vec4 v, float n){
    v.x=floor(pow(10,n) * v.x) / pow(10,n);
    v.y=floor(pow(10,n) * v.x) / pow(10,n);
    v.z=floor(pow(10,n) * v.x) / pow(10,n);
    return v;
}

and then:

if(trunc_vec(curr_eye_color,5) == trunc_vec(curr_color,5) )

n would be the precision after the floating point. It seems that this matches colors better.

https://en.wikipedia.org/wiki/Truncation

...and sorry mi english

Yes, this seems to work. I also slept on this thread that was subtly mentioned in the OP and found I was over-thinking how to use the threshold values, I got it to work by applying a small threshold as well:

if(orig_eye_color.r + threshold >= curr_color.r && orig_eye_color.r - threshold <= curr_color.r )

where threshold is an arbitrarily small number (0.01 works in this case).

It's somewhat strange you have to apply such workarounds but I guess it's not too big a deal. Thanks for your help, think I'll go with your solution since it sounds more precise.

Ok, remember that you can also increase or decrease the n function parameter for more or less presicion.

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.