Shader works in the editor but not in Game

Godot Version

4.2

Question

My Code in GDScipt:

	if Input.is_action_just_pressed("DEBUG_KEY_5"):
		animated_sprite.material.set_shader_parameter("origin_1",Color(0.043, 0.576, 0.812))
		animated_sprite.material.set_shader_parameter("new_color_1", Color(0.729, 1, 0))

And my Shader Code:

shader_type canvas_item;

uniform vec4 origin_1: source_color;
uniform vec4 new_color_1: source_color;


void fragment() {
	vec4 current_pixel = texture(TEXTURE, UV);
	if (current_pixel == origin_1)
		COLOR = (new_color_1 );
	else
		COLOR = current_pixel;
}

In the Editor the Origin_1 color get Yellow, but if i press play, nothing changed. i already read some answers. But a didn’t understand a thing so please. Explain it to me like you would to a newbie programmer

The Answers from another Post:

This is because you’re performing floating-point comparison with exact values, which will break unexpectedly due to floating-point precision errors (just like in GDScript or C#). You need to introduce an epsilon value (here, 0.001) and check whether the value is within the range of this epsilon:

(
    curr_color.r >= oldColor.r - 0.001 && curr_color.r <= oldColor.r + 0.001 &&
    curr_color.g >= oldColor.g - 0.001 && curr_color.g <= oldColor.g + 0.001 &&
    curr_color.b >= oldColor.b - 0.001 && curr_color.b <= oldColor.b + 0.001 && 
    curr_color.a >= oldColor.a - 0.001 && curr_color.a <= oldColor.a + 0.001
) {
    // Colors are approximately equal.
}

Where do i need to integrate this Code?

Floating-point comparison it’s a common problem in programming. A float value can it’s not stable and when you try to compare two float value, an infinitesimal variation can break the comparison. Instead of a exact comparison, you can perform an approximation based on an epsilon value. Here is your code changed including the approximation :

shader_type canvas_item;

uniform float epsilon = 0.0001;
uniform vec4 origin_1: source_color;
uniform vec4 new_color_1: source_color;


void fragment() {
	vec4 current_pixel = texture(TEXTURE, UV);
	if (length(current_pixel - origin_1) < epsilon)
		COLOR = (new_color_1 );
	else
		COLOR = current_pixel;
}

Here length(current_pixel - origin_1) return the distance between the two color (who are represent as vector) and compared to the epsilon value. You can change the sensibility of the comparison by changing the epsilon value.

3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.