Accessing barycentric coordinates inside fragment shader
Asked Answered
S

2

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.

Sentimentalism answered 20/8, 2014 at 5:52 Comment(1)
GLSL Spec 4.5, Ch7, Builtins does not state anything about builtins having barycentric coordinates. Perhaps you could misuse Tesselation, however I cannot comment on whether this is feasible.Nickens
M
13

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.

Mute answered 20/8, 2014 at 22:51 Comment(6)
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.Sentimentalism
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.Campaign
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?Jimmyjimsonweed
@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.Mute
@RetoKoradi, Many thanks. I actually found a part-solution for my use case on one of your other answers! 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.Jimmyjimsonweed
@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.Jamarjamb
M
2

NV_fragment_shader_barycentric

Millikan answered 2/11, 2019 at 6:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.