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])?


1 Answer 1


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.

  • \$\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, 2018 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\$ Jan 21, 2018 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\$ Jan 21, 2018 at 7:57
  • \$\begingroup\$ ...damn, now I want to try that, just for fun. :) \$\endgroup\$ Jan 21, 2018 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\$ Jan 21, 2018 at 8:36

You must log in to answer this question.

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