I am wanting a nice gradient effect. But at the minute its really patchy and you can see a seem between the two triangles. I have the following shaders vert and frag. The only thing I can think to do is to swap to a pre-generated texture.
The data is buffed as floats [x y][R G B] for two triangles, I don't think that the C++ source is worth showing.
VERT #version 330
layout(location = 0) in vec2 position;
layout(location = 1) in vec3 incolor;
smooth out vec3 color;
void main()
{
color = incolor;
gl_Position = vec4(position.x,position.y,0.0,1.0);
}
FRAG #version 330
smooth out vec4 outputColor;
smooth in vec3 color;
void main()
{
outputColor = vec4(vec3(color),1.0);
}
RESULT
Looking at the single triangle shows the blocky-ness
It's a correct behavior of linear interpolation of attributes of a quad. Remember that a quad is always rendered as two triangles. There are two possibilities to do so: with a \
diagonal or a /
diagonal as their common edge. How the attribute is interpolated now becomes ambiguous (is different in the both cases).
I'll show you an example similar to yours.
Triangles are separated by a \
diagonal.
Triangles are separated by a /
diagonal.
In both cases, the colors of the vertices are:
000000 top left
3B3B3B top right + bottom left
FFFFFF bottom right
A solution is to provide only attribute values (colors) which result in unambiguous interpolated colors. This is the case when the following holds.
Consider a line from the top left to the bottom right corner (let's call these the base vertices with an assigned base color). The top left corner has a value of 0
, the bottom right 1
. Every other vertex (in this case bottom left, top right) has to be projected orthogonally to this imaginary line and the corresponding value is assigned to this vertex. In this case (a square) the two other corners have a value of .5
each. The colors of these corners have to be a mix value of the two base colors with an alpha value corresponding to the value just calculated.
In the example above, the colors of the two other corners had to be 808080
instead of 3B3B3B
in order to make both images look equally:
In your case, you use the following colors for the vertices (at least, they appear as such in your screenshot):
000000 top left
3A3A3A top right + bottom left
595959 bottom right
So they don't fulfill the requirement from above, as 3A3A3A
isn't the mean value between the other twos.
A slightly different example demonstrates why you maybe don't just want to use .5
for the mix alpha value (which results in mean values for the two other vertices). Consider a non-square quad, like this rectangle, which uses values .5
for the two other corners, which corresponds to 808080
gray:
As you can see, the direction of the gradient isn't orthogonal to the connection line between the two "base corners", as I called them (top left -- bottom right). Now let's see what my method from above produces:
Which looks more like a linear gradient between the two corners, but in "world space", not in "texture space". You might prefer one of the two outputs over the other; I wanted to show you the difference. The values on the connection line (orthogonal projection) look like the following (they are only approximations!)
Sorry for my bad images... ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With