Barycentric coordinates of a triangle are very useful for interpolating texture coordinates, for example. Each corner contains the texture coordinate and multiplies this coordinate by the barycentric coordinate. (very simple). Also very useful is that the addition of all 3 components of the barycentric coordinate is always 1. The barycentric coordinate is therefore well suited for the interpolation of information based on corner points. But can it also be used to interpolate triangle edge based data instead of vertex based data?

The problem:

I have a triangular mesh that needs to be tessellated in different ways depending on a variable called biome. Within the tessellation control shader, each edge generates a biome number depending on the position and normals of the vertices. The normals are stored per vertex and not per face, so that neighboring faces receive the same normal for common vertices. The neighboring edge of two neighboring triangles will therefore generate the same biome number. This is very important as otherwise holes will appear during the evaluation shader. These biome numbers are stored in the following way:

A varying vec3 patch variable contains the 3 biom numbers. The number generated by vertex0 and vertex1 is stored under index [2]. The number generated by vertex1 and vertex2 is stored under index [0]. And vertex0 and vertex2 is stored in index 1. In comparison to gl_TessCoord, the biome number of the edge is therefore stored in the opposite corner. The tessellation evaluation shader receives the barycentric coordinates via the gl_TessCoord vector. So this is the point where I want to start.

Now I am looking for an algorithm that performs the interpolation between the edges.

An image shows more than 1000 words...

enter image description here

Within this triangle, the edges should retain their biome numbers (no interpolation at the edges), and the area in between should be an interpolation of the numbers.

So, as with barycentric coordinates, the sum of the weights should be around 1.

I know that the vertices are not defined within the interpolation. That will be handled later... so don't think about it.


1 Answer 1


Let $[\lambda_0, \lambda_1, \lambda_2]$ be the barycentric coordinates with respect to triangle $v_0$, $v_1$, $v_2$. In the following all subscripts are taken modulo $3$.

For each side $s_i$ (the edge $v_iv_{i+1}$) we can construct functions $h_i$. Where $$h_i = 1 - \lambda_i - \lambda_{i+1}.$$

Then we can create rational blending functions $\alpha_i = \frac{h_{i-1}}{h_{i-1} + h_i}$ and $\beta_i = \frac{h_{i+1}}{h_{i+1} + h_i}$.

By combining these blending functions we can set up the following function for side $s_i$

$$e_i = \lambda_i \alpha_i + \lambda_{i+1} \beta_i.$$ This function has the following properties. It is $1$ everywhere on $s_i$ and $0$ on all $s_j$ where $i \neq j$. It are singular at the vertices $v_i$ and $v_{i+1}$ (division by zero) and on the triangle it is smooth.

We can then interpolate edge values using:

$$F(\lambda) = \frac{\text{biom}_0 \cdot e_0 + \text{biom}_1 \cdot e_1 + \text{biom}_2 \cdot e_2}{S}$$

where $S$ is the sum of all $e_i$ in order to normalize the equation (making all functions sum to one). However, given the nice properties of barycentric coordinates in turns out that the sum of $e_i$ is already $1$. The function $\alpha_i$ and $\beta_i$ are singular at the vertices, but you said I should not worry about this.

I implemented this in a Shadertoy so you can see what the interpolation looks like:


  • $\begingroup$ wow, I am very impressed! The only thing I needed to change is: $F = (biom_0*e_1 + biom_1 * e_2 + biom_2 * e_0) / S$ so the equation was not set up for the varying biom index of the question. This is not a bad review, I just wanted to highlight it for others. Thank you very much!! +1 $\endgroup$
    – Thomas
    Jan 18 at 10:38
  • 1
    $\begingroup$ Indeed, I used an indexing scheme that seemed more natural to me. $\endgroup$
    – Reynolds
    Jan 18 at 10:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.