Data in vertex shader

Started by Dzentsetsu, October 26, 2018, 11:35:15

Previous topic - Next topic

Dzentsetsu

I have a question. Is there any significant difference between using uniform vars and in vars in vert shader? As I understand it's better to use vertex related data via in variables just for the sake of logic. Data like vertPosition, textureCoords, normals ect. Am I right? If so is there any other reason behind it? I feel I'm missing something.

KaiHH

Some things:
- "in" variables (better known as "vertex attributes") will advance automatically per-vertex or (if you configured instancing divisors) per-instance. You don't have to do anything to fetch the next vertex attribute. The GLSL vertex shader will execute the vertex shader once per vertex, automatically fetching the next vertex attributes from those attribute/in variables (or on a per-instance basis)
- vertex attributes can be sourced from arbitrarily large buffer objects. You can have hundreds of millions of vertices with their attributes in a GL buffer object. The limit is only the virtual address space (swapping to system memory will occur if the physical memory space is filled)
- Uniforms on the other hand are, as their name implies, _uniform_ over all vertex shader invocations. That means, they do not advance automatically and every vertex shader invocation sees the same data. They are not meant for per-vertex data
- When backing uniforms by uniform buffer objects, the maximum size of those is quite limited. You cannot store millions of vertices in a uniform buffer object
- Let's say you did put all vertex data into a uniform buffer, then fetching of the correct vertex would require extra/manual GLSL instructions, likely depending on gl_VertexID, which might slow things down (the order of vertex shader invocations and fetching of the uniforms might then also not be optimal -> scattered and not coalesced -> bad)

In short:
- Use uniforms only for data which potentially _every_ vertex shader invocation must access the same data from. A good example for this are model, view and projection matrices, since every vertex shader invocation usually performs transformations with always the same matrices on the varying vertex attributes.
- Use vertex attributes for per-vertex (or per-instance) data, which every shader needs to process a different vertex with different attributes

There are more advanced techniques for manual multi-index vertex attribute fetching, since with OpenGL you can only have a single indices/elements stream/buffer over all vertex attribute streams. But those still use other kinds of buffer objects like Shader Storage Buffer Objects, which, like normal Vertex Buffer Objects, have no constraining size limit.
So in 99.9999% of the cases, you juse use normal vertex attributes to fetch vertex data and if you want to allow more controlled, arbitrary access to the vertex attributes of a potentially very large vertex stream, then use Shader Storage Buffer Objects (and certainly not uniforms/uniform buffer objects).

Dzentsetsu

Thanks for complete answer. It clears a lot for me!