gl_BaryCoordEXT vs gl_BaryCoordNoPerspEXT in GLSL
In OpenGL and Vulkan shading via the
GL_EXT_fragment_shader_barycentric extension,
gl_BaryCoordEXT and gl_BaryCoordNoPerspEXT are
built-in fragment shader input variables that expose the barycentric
coordinates of a fragment within a primitive. The fundamental difference
between them lies in how interpolation is handled:
gl_BaryCoordEXT provides perspective-correct barycentric
coordinates, whereas gl_BaryCoordNoPerspEXT provides
screen-space, linearly interpolated coordinates without perspective
correction.
Understanding Barycentric Coordinates
Barycentric coordinates describe a point inside a triangle as a
weighted combination of the triangle's three vertices. Represented as a
vec3 \((u, v, w)\) where
\(u + v + w = 1.0\), each component
corresponds to the weight or relative distance of the current fragment
with respect to one of the vertices.
gl_BaryCoordEXT: Perspective-Correct Interpolation
gl_BaryCoordEXT interpolates coordinates across the
triangle taking perspective projection into account.
- Mechanism: The values are interpolated linearly in
clip space (divided by \(W\) at each
vertex) and then recovered via perspective division per pixel, matching
the behavior of vertex attributes qualified with
smooth. - Visual Result: The rate of change of the coordinates matches the perspective distortion of the 3D surface. Features rendered using these coordinates compress as the primitive recedes into the distance.
- Common Use Cases:
- Procedural textures applied directly to geometry surfaces.
- Wireframes or inner-triangle patterns that should shrink with distance and respect 3D depth perspective.
- Custom attribute interpolation where perspective projection must be preserved.
gl_BaryCoordNoPerspEXT: Linear Screen-Space Interpolation
gl_BaryCoordNoPerspEXT interpolates coordinates linearly
across the screen-space projection of the triangle, ignoring the depth
(\(W\)) component.
- Mechanism: The coordinates are interpolated
directly across the 2D window coordinate space, matching the behavior of
vertex attributes qualified with the
noperspectivequalifier. - Visual Result: The coordinates change at a constant rate per pixel across the primitive, regardless of the angle, depth, or tilt of the primitive relative to the camera.
- Common Use Cases:
- Constant-width wireframe rendering, where line thickness along the edges of triangles must remain consistent in screen pixels regardless of camera distance.
- Edge-detection algorithms, anti-aliasing techniques, and screen-aligned stylized outlines.
- 2D user interface overlays or HUD elements mapped across 3D meshes.
Summary of Differences
| Feature | gl_BaryCoordEXT |
gl_BaryCoordNoPerspEXT |
|---|---|---|
| Interpolation Type | Perspective-correct | Screen-space linear |
| Attribute Equivalent | smooth interpolation |
noperspective
interpolation |
| Perspective Division | Yes (respects \(W\) coordinate) | No (ignores \(W\) coordinate) |
| Pixel Step Size | Non-linear across screen space | Uniform across screen space |
| Primary Use Case | 3D surface shading and texturing | Constant-width screen-space wireframes |