Trying to understand why vertex() and fragment() COLOR produces different result. I have a simple Sprite2D CanvasTexture with the following shader code attached. The vertex() version gives a gradient white/green in the Y axes, while the fragment() (when you un-comment the function call) produces a split solid white / green divided along the Y axes. Any thought?

shader_type canvas_item;

vec4 xcolor(in vec2 uv){
	if (uv.y <=0.5) {
		return vec4(1,1,1,1);	
	} else {
		return vec4(0,1,0,1);	
	}
}

void vertex() {
	//produces gradient shade in the Y
	COLOR=xcolor(UV);
}

void fragment() {
	// Uncomment to see splits white and green in the Y.
//	COLOR=xcolor(UV);
}


vertex is calculated per vertex. fragment is done per pixel.
when a vertex is applied color, it will blend the result between connected vertices. your fragment is just cutting the texture in half.
don't use conditionals in shaders "if else" they are bad for the GPU and can even give you errors. when you use if-else, the GPU is going to calculate every single condition and waste processing power (unless it's a very modern one). use a texture for this, even if it's very small, or color your vertices before sending them to the gpu.

Jesusemora is correct. To elaborate just a little, vertexes are the points in a polygon of a mesh. Most often in 2D it will be like you have here, with 4 of them, one in each corner. In the vertex() function, COLOR serves to get/set the color stored exactly in that particular vertex. Sometimes meshes will have a vertex color already baked in, if an artist was using it for something. In the fragment() function, the get and set from color actually do two different things: getting COLOR gets the now-interpolated value from the vertex colors. Setting COLOR sets usually the final color you see rendered on the texture in 2D, although that isn't true if there is 2D lighting involved.

As for avoiding if/else, often you can use the step function instead, like this:

vec4 xcolor(in vec2 uv){
	float s = step(0.5, uv.y);
	return vec4(0.0,1.0,0.0,1.0) * s + vec4(1.0,1.0,1.0,1.0) * (1.0 - s);
}

For visualization/debugging purposes, I would like to set the COLOR for each vertice, so only the 4 corners have some color. Is there some render_mode that does that or some other method?

  • xyz replied to this.

    Do you care what the 4 colors are? Just using the UVs directly is pretty good for that debugging purpose.

    void vertex() {
    	COLOR = vec4(UV, 0., 1.);
    }

    That creates this:

    wyattbiker For visualization/debugging purposes

    What do you want to visualize?