1

I would like to understand how to optimize the 3D objects drawing using also normals.

For example I have a cube: it has 8 vertices, and 6 faces that could be rapresented as 12 triangles.

(I've used the cube in order to simplify the question, but in general if you have triangles that represent plane surfaces the question is still valid)

If so, I have a VertexBuffer with 8 vertices, and an IndexBuffer of 36 items (12t*3v each).

If I use the OpenGL function DrawElements in my code. This works!

The next step is introducing the normals, because I want the lights effects.

In this example I thought to use a NormalsBuffer with a normal for each triangle.

3D objects

In order to get the right normal, I thought to use VertexShader and retrive the value just dividing the gl_VertexID by 3.

int triangleIndex = (gl_VertexID/3)

the triangleIndex is the Normals index to use to retrive normal in NormalsBuffer.

I didn't find any example or document that explains how to optimize the normal's vectors usage.

Is it my idea valid?

And if Yes how can I get the normal vector from Vertex Shader?

I have found this Post inspiring "Rendering meshes with multiple indices", but not useful because it miss usable code.

Tostone
  • 95
  • 1
  • 9
  • 1
    Is your question about "3D objects with normals" *in general* or cubes *specifically*? The question you cited explains this *in general* (namely, that general meshes aren't faceted and thus don't have this problem). Your cube example is very specific and thus is a different question. – Nicol Bolas Feb 14 '22 at 16:49
  • I've used the cube in order to simplify the question, but in general if you have triangles that represent plane surfaces the question is still valid. – Tostone Feb 15 '22 at 07:37
  • If it's a general question, then it's a duplicate of the other general question. – Nicol Bolas Feb 15 '22 at 14:23

2 Answers2

1

Your method will not work. Not unless you're indirectly accessing the positions too.

gl_VertexID is the vertex's index within the rendering stream. When doing array rendering, each vertex has a unique index (since the indices go from start to end in the array). For indexed rendering, each vertex's index is... its index. From the index array. That's the point of indexing.

So if you have 8 vertices, your gl_VertexID value will be on the range [0, 7].

Furthermore, vertex shaders explicitly require the user to not do anything that would cause a particular VS for a specific vertex index (and instance) to produce a different value for a given draw call. That is, if gl_VertexID is 3, your code is required to produce binary identical outputs no matter when that index is 3.

The only way to get around this is to not use indexed rendering at all. To manually do all vertex reading from buffers, positions and normals alike. With such rendering, gl_VertexID will just be a sequentially increasing value.

Since you know that your object is a cube, you can synthesize both the normal and position indices in the VS itself without having to read memory.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • But this is a waste of memory, don't you think? it seems to me strange that no one thought how avoid this. Maybe the designers privileged the speed. – Tostone Feb 15 '22 at 07:34
  • @Tostone: "*But this is a waste of memory, don't you think?*" No. Most meshes are not faceted. – Nicol Bolas Feb 15 '22 at 14:47
0

So the solution should be this:

![enter image description here

Tostone
  • 95
  • 1
  • 9
  • sorry it was my mistake I have corrected the image! in any case the solution works because I tried it. The primary key is Vertex+Normal. It works because the vertex is duplicated (2 -> V5 has N0) and (7 -> V5 has N1). The index buffer point 2 and 7 that are virtualy differents. – Tostone Feb 15 '22 at 14:48
  • You still need individual lists of indices, so that you can map from vertex index 0 to position index V0 and normal index N0. The need for such lists is precisely why graphics APIs *don't* have multiple index lists. – Nicol Bolas Feb 15 '22 at 14:48