What is wrong with my shader which won't work at runtime?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Rickers

So i’ve been trying to create a shader which will change the colour of various items of clothing which can be put on a randomly generated NPC. Sometimes this requires multiple colours to be shifted (to distinguish different parts of the sprite).

Whilst the code looks great in the editor, I cannot get it to work at runtime.

One solution I found online was to use the Round(COLOR) function, which makes the shader work at runtime, but the problem is that it turns the ENTIRE texture the same colour, ignoring other parameters. I have no idea what do to, either this is a bug, or its a result of my inexperience with Shaders, but using code i’ve found online doesn’t seem to work either.

This is the code as it should work (without the ROUND functions added)

shader_type canvas_item;
uniform vec4 pre_torso_colour:hint_color;
uniform vec4 new_torso_colour:hint_color;
uniform vec4 pre_skin_colour:hint_color;
uniform vec4 new_skin_colour:hint_color;
uniform vec4 pre_legs_colour:hint_color;
uniform vec4 new_legs_colour:hint_color;
void fragment(){
	COLOR = texture(TEXTURE,UV);
	if (COLOR == pre_torso_colour){
		COLOR = new_torso_colour;
	} else if(COLOR == pre_skin_colour) {
		COLOR = new_skin_colour;	
	} else if(COLOR == pre_legs_colour){
		COLOR = new_legs_colour;
	}
}

This works PERFECTLY in the editor, but at runtime it just shows the default, unedited sprite.

Now, if I add the ROUND parts:

shader_type canvas_item;
uniform vec4 pre_torso_colour:hint_color;
uniform vec4 new_torso_colour:hint_color;
uniform vec4 pre_skin_colour:hint_color;
uniform vec4 new_skin_colour:hint_color;
uniform vec4 pre_legs_colour:hint_color;
uniform vec4 new_legs_colour:hint_color;
void fragment(){
	COLOR = texture(TEXTURE,UV);
	if (round(COLOR) == round(pre_torso_colour)){
		COLOR = new_torso_colour;
	} else if(round(COLOR) == round(pre_skin_colour)) {
		COLOR = new_skin_colour;	
	} else if(round(COLOR) == round(pre_legs_colour)){
		COLOR = new_legs_colour;
	}
}

The entire sprite just turns red, (the colour of the new_torso_colour).

Anyone know what what the issue is?

Thanks

EDIT:

So I tested both with Icon.png and only the Round version works at runtime, so I can only assume something is up with the sprites I am using, or it could be some other issue they came from photoshop export .png if that helps, if anyone has any suggestions please let me know.

Both versions are working flawless in editor and at runtime at my PC.
(tested with icon.png as a sprite)

whiteshampoo | 2021-01-28 06:34

Thanks for testing, I just tested with the Icon (should have done that earlier) and it worked just fine. I wonder what the problem is with the other sprites then, they are both .png as well, but they did come from Photoshop so maybe that has something to do with it?

Rickers | 2021-01-28 15:24

Can you post the sprites somewhere?

DDoop | 2021-01-28 16:45

Yeah here they are, these are just one “set”, but the idea is that they are put together into their own separate nodes beneath a kinematic body.

e.g.

  • Kinematic Body
  • Children
  • Torso
  • Legs
  • Head

etc…

Then the shader material is applied to the Kinematic body, and all the children have “use parent material” marked as True.

Rickers | 2021-01-28 17:45