I have an OpenGL question!

Say I have data, interleaved in the format

[vec3 normal, vec3 vert1, vec3 vert2, vec3 vert3]

all stored in one VBO (one set per triangle). My vertex shader would have the following attributes:

in vec3 normal;
in vec3 position;

Is it possible to extract the data this way? Or would I need to duplicate the normal for each vertex (eg. [vec3 normal, vec3 vert1, vec3 normal, vec3 vert2, vec3 normal, vec3 vert3])?


OpenGL has no built-in concept of triangle or face normals; only vertices have normals.

If you wish for every fragment/pixel within the triangle to be drawn using the same normal, then you will need to provide that same normal for each of the three vertices that define the triangle. So yes, you need to duplicate the normal for each vertex.

| improve this answer | |
  • \$\begingroup\$ Ok, thank you. I did not expect OpenGL to have a concept of normals, I was just wondering how to distribute data stored in a weird way! \$\endgroup\$ – Fuzzyzilla Jan 21 '18 at 7:41
  • \$\begingroup\$ @Fuzzyzilla If you really wanted to be silly, you could probably bind the whole data buffer as a buffer texture of type (GL_RGB32F), instead of as a VBO, and then fetch the vertex positions and triangle normals in your vertex shader, as if it was texture data, based upon the gl_VertexID. That would require an OpenGL context version 4.0 or higher. And like I said, it's probably a pretty silly way to do it, unless you're under severe memory pressure. \$\endgroup\$ – Trevor Powell Jan 21 '18 at 7:52
  • \$\begingroup\$ I mean, that would support the "one normal per triangle" data format you have now. But it would be highly unusual, and I've never tried doing something quite like that. OpenGL wouldn't hold your hand through it. :) It would involve something like int triangleIndex = (gl_VertexID/3)*4; and int vertexIndex = triangleIndex + mod(gl_VertexID,3);, and sampling those two points out of the buffer texture, instead of grabbing the data from vertex attributes. \$\endgroup\$ – Trevor Powell Jan 21 '18 at 7:57
  • \$\begingroup\$ ...damn, now I want to try that, just for fun. :) \$\endgroup\$ – Trevor Powell Jan 21 '18 at 7:57
  • \$\begingroup\$ Another way would be to calculate the normal from the positions at run-time in a geometry shader, but that's definitely not going to be faster. \$\endgroup\$ – Maximus Minimus Jan 21 '18 at 8:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.