Shader Vertex vs Fragment COLOR produces different result. Why?
Asked Answered
B

6

0

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);
}


Blacklist answered 16/11, 2023 at 0:50 Comment(0)
S
0

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.

Sibelius answered 16/11, 2023 at 1:4 Comment(0)
P
0

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);
}
Paprika answered 16/11, 2023 at 2:25 Comment(0)
B
0

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?

Blacklist answered 16/11, 2023 at 17:59 Comment(0)
E
0

You might want to look into barycentric coordinates.

Enslave answered 16/11, 2023 at 20:49 Comment(0)
P
0

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:

Paprika answered 16/11, 2023 at 21:56 Comment(0)
P
0

Blacklist For visualization/debugging purposes

What do you want to visualize?

Pralltriller answered 16/11, 2023 at 21:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.