Shader position vec4 or vec3

11,197

For vertex attributes, this will not matter. The 4th component is automatically expanded to 1.0 when it is absent.

That is to say, if you pass a 3-dimensional vertex attribute pointer to a 4-dimensional vector, GL will fill-in W with 1.0 for you. I always go with this route, it avoids having to explicitly write vec4 (...) when doing matrix multiplication on the position and it also avoids wasting memory storing the 4th component.

This works for 2D coordinates too, by the way. A 2D coordinate passed to a vec4 attribute becomes vec4 (x, y, 0.0, 1.0). The general rule is this: all missing components are replaced with 0.0 except for W, which is replaced with 1.0.

However, to people who are unaware of the behavior of GLSL in this circumstance, it can be confusing. I suppose this is why most tutorials never touch on this topic.

Share:
11,197

Related videos on Youtube

Skides
Author by

Skides

Updated on June 04, 2022

Comments

  • Skides
    Skides almost 2 years

    I have read some tutorials about GLSL. In certain position attribute is a vec4 in some vec3. I know that the matrix operations need a vec4, but is it worth to send an additional element? Isn't it better to send vec3 and later cast in the shader vec4(position, 1.0)? Less data in memory - it will be faster? Or we should pack an extra element to avoid casting?

    Any tips what should be better?

    layout(location = 0) in vec4 position;
    MVP*position;
    

    or

    layout(location = 0) in vec3 position;
    MVP*vec4(position,1.0);
    
  • Skides
    Skides over 10 years
    Does it mean that I can use: glBufferSubData(GL_ARRAY_BUFFER, 0, vertex*3, data); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); and in shaders use the "layout(location = 0) in vec4 position;" expression?
  • Andon M. Coleman
    Andon M. Coleman over 10 years
    Yes, that is what this means. If you do this, GLSL will add a 1.0 for W every time you try to access it.
  • ThePhD
    ThePhD over 8 years
    Just a quick extra question: does this apply to more than GLfloat? That is, would the same expansion happen for a dvec2 -> dvec4 or ivec2 -> ivec4 ?
  • Andon M. Coleman
    Andon M. Coleman over 8 years
    @ThePhD: Yes, this behavior applies throughout the pipeline (from texture fetches to vertex attributes). "... for uvec4 data, respectively. Unused components are filled in with (0, 0, 0, 1) (where 0 and 1 are either floating-point or integer values, depending on the format)." See paragraph 3 here.
  • ThePhD
    ThePhD over 8 years
    Thanks, that actually really helps me! (I was writing a verifier that verified one GLSL / HLSL layout matched with the next, and that input vertex data matched with the layout data being input, mostly for debug purposes while I try to figure out how NSight works.)
  • ThePhD
    ThePhD over 8 years
    Ooone last question.... does this only apply to compatibility profiles? (I'm still tracking one last bug that seems to be affected by my stride inputs / outputs...)
  • Andon M. Coleman
    Andon M. Coleman over 8 years
    @ThePhD: Sorry, for the delay. Yes. That behavior stretches back to the existence of the old ARB assembly shading language. It's something GL has always done; filling in 1.0 for the w (or a) coordinate makes things without a homogeneous coordinate scale properly and without an alpha channel opaque.
  • keaukraine
    keaukraine over 8 years
    Does the same apply for OpenGL ES?
  • Andon M. Coleman
    Andon M. Coleman over 8 years
    @keaukraine: Yes, this behavior has been a part of OpenGL since it was created. The fixed-function pipeline even works this way. This is why RGB textures have an implicit 1.0 for the alpha channel they do not store.
  • PeterT
    PeterT over 6 years
    I feel like this answer could be improved with reference to relevant parts of the spec.