3
\$\begingroup\$

A shader normally has values that vary per-vertex and values that vary per-fragment.

Can you have values that vary only per primitive, such as per-triangle or per-quad?

\$\endgroup\$
4
  • \$\begingroup\$ Maybe you can use glVertexAttribDivisor: opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisor.xml- but I don't know, if it will work with ordinary draw commands (without instanced drawing). \$\endgroup\$
    – zacharmarz
    Commented May 22, 2011 at 11:12
  • \$\begingroup\$ @zacharmarz that ought to go in an answer so it can be enlarged upon; it looks promising, I hadn't seen that before; it would require all bits I drew to be the same size, of course, but using it to give different transform for each unit and draw an army of the same unit, then it might be great! \$\endgroup\$
    – Will
    Commented May 23, 2011 at 6:42
  • 1
    \$\begingroup\$ @Will If you're looking to draw an army with different transforms for each unit, instanced drawing is definitely what you want. I don't think there's a way to have per-triangle values without duplicating them to all three vertices. \$\endgroup\$ Commented Nov 30, 2013 at 20:25
  • 1
    \$\begingroup\$ Adding a geometry shader that takes a triangle as input and outputs the same triangle but with the extra attribute added (perhaps read from a texture) may be another way. But - if you're looking for this to try save storage or calculations, be aware that it's often faster to just accept the extra storage or calculations in exchange for a simpler setup. \$\endgroup\$ Commented Dec 3, 2013 at 10:09

2 Answers 2

2
\$\begingroup\$

No, you can't, there is no such concept in the graphics pipeline.

If you are using instancing, you can control the rate at which the instanced attributes advance for a given attribute index. This can be done independently for each attribute, and is probably the closest you're going to get to what you are asking for using the actual functionality of the pipeline. It may not be flexible enough for your needs, however, and it does require instanced rendering.

You can, of course, always build this abstraction into your CPU-side rendering layer by having a buffer object that understands what kind of primitive it stores (triangles, quads, lines, et cetera) and provides a way to manipulate per-primitive attribute buffers which, under the hood, it will replicate out into the real vertex buffer on a per-vertex basis. This won't give you the space-saving advantages, but it would present the simpler client-side interface that you are probably interested in.

\$\endgroup\$
1
  • \$\begingroup\$ And while it doesn't work portably right now in webGL, instancing has started to appear on Chrome as an extension. \$\endgroup\$
    – Will
    Commented Dec 17, 2013 at 6:26
0
\$\begingroup\$

For this pupose, you may use buffer texture and access it in the fragment shader using gl_PrimitiveID.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ This answer would be even better if it included a short example of how to use gl_PrimitiveID this way. \$\endgroup\$
    – DMGregory
    Commented Apr 13, 2018 at 11:48
  • \$\begingroup\$ gl_PrimitiveID may implicitly add a geometry shader, massively decreasing performance \$\endgroup\$
    – user369070
    Commented Oct 5, 2021 at 8:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .