I'm trying to make a triangle like the one in the right in the following picture:
The problem is that what I want to achieve is a gradient of color from vertexes 1 and 2 proyected from C.
As far as I know this is not possible since vertex C must have a color on it's own, which will also blend into 1 and 2's colors, like in the left triangle of the picture. If I set C to a middle point color, this generates an undesired result, since the taller the triangle is made, the less noticiable are the other vertex's colors.
Line C1 should be black, and line C2 should be white.
Is there any way to achieve this in OpenGL?
There are two ways, but I don't know which makes most sense for your application. At a very high level:
Map a texture to the triangle. As the gradient is very smooth, it doesn't need to be very high resolution, and you can let linear filtering do the work for you.
Use a shader. More work to set up, but also more flexible, and gives you a 'perfect' result at any scale/resolution.
Update: if you're going to use a shader, the idea is the following.
Pass a varying vec2 coords
from the vertex shader to the fragment shader. Set the value for point 1 to 0,0
, for point 2 to 1,0
and for point C to 0,1
. To get these values into the vertex shader, use an attribute
. Varying values will be interpolated across the triangle, much like texture coordinates and colours would. So the coords
variable is mapped to your triangle like this:
y
1 +-----+
|\ |
|#\ |
|##\ |
|###\ |
|####\|
0 +-----+ x
0 1
The fragment shader receives a coords
value somewhere inside the hashed area. To figure out how much of each colour you need to blend, compute the line through coords
and 0,1
, and find its intersection with the x
axis. Thanks to the coordinate system of coords
, this is a simple operation: simply divide coords.x
by coords.y
. Call this f
. (Note that this will give division by zero at point C, but this is expected as you never defined the colour there. You can check for that explicitly in the shader if you want.)
Indicating coords
with c
and representing the line with .
characters, f
ends up somewhere between 0 and 1:
y
1 +-----+
|\ |
|.\ |
|#c\ |
|#.#\ |
|##.#\|
0 +--f--+ x
0 1
Now let's say you have uniform vec4 colour1
and uniform vec4 colour2
to define the colour at point 1 and 2, respectively. Then it's a simple matter of blending these: taking f
fraction of colour2
and 1-f
fraction of colour1
and adding them together. The GLSL mix
function does exactly this.