Computing Barycentric Coordinates in GLSL
This article explains how to compute barycentric coordinates for an arbitrary point relative to a triangle's vertices using OpenGL Shading Language (GLSL). Barycentric coordinates express any point on a triangle's plane as a weighted sum of the triangle's three vertices, providing an essential mechanism for attribute interpolation, ray-triangle intersection testing, and procedural geometric effects. Below is the mathematical formulation using Cramer's rule alongside an optimized, ready-to-use GLSL function.
The Mathematical Formulation
Given a triangle defined by three vertices \(A\), \(B\), and \(C\), any point \(P\) lying on the plane of the triangle can be expressed as:
\[P = uA + vB + wC\]
where \(u\), \(v\), and \(w\) are the barycentric coordinates satisfying the constraint:
\[u + v + w = 1 \implies u = 1 - v - w\]
Substituting \(u\) gives the vector formulation relative to vertex \(A\):
\[P - A = v(B - A) + w(C - A)\]
Let \(v_0 = B - A\), \(v_1 = C - A\), and \(v_2 = P - A\). This yields a linear system of two equations:
\[(v \cdot v_0 + w \cdot v_1) \cdot v_0 = v_2 \cdot v_0\] \[(v \cdot v_0 + w \cdot v_1) \cdot v_1 = v_2 \cdot v_1\]
Expanding these equations produces a \(2 \times 2\) system that can be solved directly for \(v\) and \(w\) using Cramer's rule via dot products.
GLSL Implementation
The dot-product method works reliably for both 2D points
(vec2) and coplanar 3D points (vec3):
vec3 computeBarycentric(vec3 p, vec3 a, vec3 b, vec3 c) {
vec3 v0 = b - a;
vec3 v1 = c - a;
vec3 v2 = p - a;
float d00 = dot(v0, v0);
float d01 = dot(v0, v1);
float d11 = dot(v1, v1);
float d20 = dot(v2, v0);
float d21 = dot(v2, v1);
float denom = d00 * d11 - d01 * d01;
// Guard against degenerate triangles
if (abs(denom) < 1e-6) {
return vec3(-1.0);
}
float v = (d11 * d20 - d01 * d21) / denom;
float w = (d00 * d21 - d01 * d20) / denom;
float u = 1.0 - v - w;
return vec3(u, v, w);
}Interpreting the Results
The returned vec3(u, v, w) maps weights to vertices
\(A\), \(B\), and \(C\) respectively:
- Inside the Triangle: The point \(P\) is strictly inside the triangle if \(u \ge 0\), \(v \ge 0\), and \(w \ge 0\).
- On an Edge or Vertex: If any coordinate equals \(0\), \(P\) lies on the edge opposite to that vertex. If two coordinates equal \(0\), \(P\) coincides with the remaining vertex.
- Outside the Triangle: If any coordinate is negative, \(P\) lies outside the triangle boundary.