6

In the fragment shader, values are naturally interpolated. For example, if I have three vertices, each with a color, red for the first vertex, green for the second and blue for the third. If I render a triangle with them, the expected result is the common triangle.

Obviously, OpenGL calculates the interpolation coefficients (a, b, c) for each point inside the triangle. Is there any way to explicitly access these values or would I need to calculate the fragment coordinates of the three vertices and find the barycentric coordinates of the point myself? I know this is perfectly feasible, but I thought OpenGL could have provided something.

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • [GLSL Spec 4.5, Ch7, Builtins](https://www.opengl.org/registry/doc/GLSLangSpec.4.50.pdf) does not state anything about builtins having barycentric coordinates. Perhaps you could misuse [Tesselation](http://ogldev.atspace.co.uk/www/tutorial30/tutorial30.html), however I cannot comment on whether this is feasible. – Stefan Hanke Aug 20 '14 at 09:21

2 Answers2

12

I'm not aware of any built-in for getting the barycentric coordinates. But you should't need any calculations in the fragment shader.

You can pass the barycentric coordinates of the triangle vertices as attributes into the vertex shader. The attribute values for the 3 vertices are simply (1, 0, 0), (0, 1, 0), and (0, 0, 1). Then pass the attribute value through to the fragment shader (using a varying variable in legacy OpenGL, out in vertex shader and in in fragment shader in core OpenGL). Then value of the variable received by the fragment shader are the barycentric coordinates of the fragment.

This is very similar to the way you would commonly pass texture coordinates into the vertex shader, and them pass them through to the fragment shader, which receives the interpolated values.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • Understood. Although my scenario is more complex than this triangle, I can use the same idea. Thank you for the answer, I'll update here when I can. – Daniel Pinto Coutinho Aug 21 '14 at 06:10
  • 4
    I'd like to add that what this will result in are _not_ the barycentric coordinates the GL will calculate during rasterization, since the rasterizer works in two-dimensional screen space. What you get here are the barycentric coordinates with respect to the 3D object space of the triangle, undistorted by the prespective. If you want the real screen-space barycentric coordinates, you should add the `noperspective` qualifier. It is not really clear from the question which ones are the desired values. – derhass Aug 21 '14 at 13:30
  • 3
    For a complex mesh, do you need three `vec3` barycentric co-ordinate per vertex? Or can you get away with just one? If three, how then do you prevent these from conflicting between different but neighbouring triangles? – Engineer Jan 27 '15 at 11:15
  • @NickWiggill Good question... I'm not sure how you would do that best. If you would otherwise have meshes with shared vertices, this certainly looks like it becomes tricky. You couldn't easily share this new attribute for vertices that are used by multiple triangles. I'll post if something comes to mind, sounds like an interesting problem. – Reto Koradi Jan 29 '15 at 06:32
  • @RetoKoradi, Many thanks. I actually found a part-solution for my use case on [one of your other answers](http://stackoverflow.com/questions/24839857/wireframe-shader-issue-with-barycentric-coordinates-when-using-shared-vertices)! The only problem is that I have a central vertex in the quad, and so would love to have both diagonals (in x-form). I think it will be possible to determine in fragment shader how close we are to diagonals by checking modulus on both x & y axes, and render there... which should be a complete solution. Will post there if so. – Engineer Jan 29 '15 at 10:42
  • @ArcaneEngineer. I think the 4-color theorem applies to sharing vertices on a mesh with the connectivity of a plane. Wikipedia says a torus requires up to 7 colors. But maybe a vec4 could be made to work well enough for most tings. – Samuel Danielson Feb 19 '16 at 09:47
2

NV_fragment_shader_barycentric

Anton Duzenko
  • 2,366
  • 1
  • 21
  • 26