how are colors interpolated ?

the situation : i want to create a big blurry texture for my whole outdoor map. therefore, i calculate for every pixel the position where its corresponding landscape point is.
now i end up on a triangle. i know it’s textures, and the density of each texture at each vertex, which is stored in its color.
maybe you know the method : http://www.delphi3d.net/articles/viewarticle.php?article=terraintex.htm

well, for the blurry texture, i need to calculate a specific pixels color. in others words : i got 3 vertices, 3 colors. how to calclate a color on a specific point somewhere on this triangle ?

OpenGl already interpolates vertices color.
Or I did not understood what you want to achieve ?

i need to interpolate it manually

If I understand you correctly, you want to reproduce the color interpolation of OpenGL. But this is not possible, because it is not exactly specified how the graphics hardware has to do it…

If it is not necessary to get exactly the same result as OpenGL would produce, you can use the following algorithm:
Linearely interpolate between the vertices to get the colors at the edges of the polygon and the interpolate along the scanlines to get the inside pixels. I think this is what most graphic cards will do, but don’t quote me on that…

Originally posted by HamsterofDeath:
i need to interpolate it manually

There are lots of ways to do this.

One simple way would be to compute barycentric weights, and do a weighted
average.

Another would be to compute screen-space plane equations for each component independently.

I’ll leave the how-to for these approaches as an exercise for other posters. (Unless nobody knows how. )

Cass

Bi-linear interpolation …

/** Interpolate the dependent axis value of a point.
@param xSw X coordinate of south-western point.
@param ySw Y coordinate of south-western point.
@param zSw Z coordinate of south-western point.
@param xSe X coordinate of south-eastern point.
@param ySe Y coordinate of south-eastern point.
@param zSe Z coordinate of south-eastern point.
@param xNw X coordinate of north-western point.
@param yNw Y coordinate of north-western point.
@param zNw Z coordinate of north-western point.
@param xNe X coordinate of north-eastern point.
@param yNe Y coordinate of north-eastern point.
@param zNe Z coordinate of north-eastern point.
@param x X coordinate of point in question.
@param y Y coordinate of point in question.
receptor.
*/
double interpolate(
double xSw, double ySw, double zSw,
double xSe, double ySe, double zSe,
double xNw, double yNw, double zNw,
double xNe, double yNe, double zNe,
double x, double y
) const;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Interpolate the dependent axis value of a point.

double MgBilinearInterpolator3D::
interpolate(
double xSw, double ySw, double zSw,
double xSe, double ySe, double zSe,
double xNw, double yNw, double zNw,
double xNe, double yNe, double zNe,
double x, double y
) const
{
double delX = (x - xSw) / (xSe - xSw);
double delY = (y - ySw) / (ySe - ySw);

double delX1 = 1.0 - delX;
double delY1 = 1.0 - delY;
return
delY1delX1zSw + delYdelX1zSe +
delY* delX zNe + delY1 delX*zNw;
}

well, thanks for the code.

but : does it matter if i switch the points ? there is no “north” and “south” in my triangle.
and more important : i have a triangle, not a quad.

and what exactly does this function do ?

i get a value back…but what do to with it ?

Linearely interpolate between the vertices to get the colors at the edges of the polygon and the interpolate along the scanlines to get the inside pixels. I think this is what most graphic cards will do, but don’t quote me on that…

getting the colors of the outer lines is no problem, since it’s an interpolation between 2 points. but how to go on ?

Just to restate the problem: You have three vertices (v1, v2, v3), each with an associated color (c1,c2,c3), and you want to generate a color c4 at vertex v4 using a weighted average of colors from v1, v2 and v3. One such solution is given below.

General solution: Calculate the absolute distance between each vertex and v4, denoted d1, d2, d3. Let the total distance between all vectors and v4 be D = d1+d2+d3. Then the weighting factor associated with each vertex is associated with the absolute distance the vertex is from v4 relative to the total distance to v4 of all the points:

w1 = (1 - d1/D)/(N-1)
w2 = (1 - d2/D)/(N-1)
w3 = (1 - d3/D)/(N-1)

N = 3, the number of vertices used to calculate D.

The color at v4 is then c4 = w1c1 + w2c2 + w3*c3

Note that this technique easily expands to any number of vertices describing your polygon, and in fact is not restricted to a planar surface. Hope it helps.

The distance-based weighting approach is an interesting one, though I think it’d have a somewhat strange effect when a triangle was scaled between skinny and fat.

Since nobody else has posted, I’ll briefly state how to do plane equations and barycentrics.

Plane equations:

Each component of color is a plane equation of the form

f = Ax + By + C

We know that

f1 = A(v1.x) + B(v1.y) + C(v1.z)
f2 = A(v2.x) + B(v2.y) + C(v2.z)
f3 = A(v3.x) + B(v3.y) + C(v3.z)

or

|f1| | v1.x v1.y v1.z | | A |
|f2| = | v2.x v2.y v2.z | | B |
|f3| | v3.x v3.y v3.z | | C |

So if we rewrite this as

| v1.x  v1.y  v1.z |

M = | v2.x v2.y v2.z |
| v3.x v3.y v3.z |

Then the plane equation is

| A | | f1 |
| B | = (M^1) | f2 |
| C | | f3 |

This and numerous other interesting observations are noted in http://www.cs.unc.edu/~olano/papers/2dh-tri/ .

Barycentric equations:

Barycentric is just a weighted average, so

f = Af1 + Bf2 + C*f3.

But the weights are based on distance from each edge. A vertex v on edge(v2,v3) has an A weight of 0. And the general formula is

A = dist( v, edge(v2,v3) ) / dist( v1, edge(v2,v3) )
B = dist( v, edge(v3,v1) ) / dist( v2, edge(v3,v1) )
C = dist( v, edge(v1,v2) ) / dist( v3, edge(v1,v2) )

For points inside a triangle, it’s true that A+B+C==1, which can be useful.

The interesting thing about Barycentric weights is that they’re independent of the attribute being interpolated, so once you’ve computed them they work for all attributes.

But, you have to compute new barycentric weights for each point in the triangle.

Anyway, I hope this helps.

Thanks -
Cass

thx