0
votes

I'm learning modern OpenGL using the tutorial from opengl-tutorial.org.

Their vertex shaders alwas use the type vec3 to pass vertex coordinates to the vertex shader. According to the manuals it should be possible to use the type float as well. As my application gets the vertex coordinates as an array of floats I tried to use float to pass them, which doesn't work as expected. Even the Tutorial 5 : A Textured Cube of the tutorials shows the effect. If I change the vertex shader code from:

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

// Output data ; will be interpolated for each fragment.
out vec2 UV;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main(){

    // Output position of the vertex, in clip space : MVP * position
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
    
    // UV of the vertex. No special space for this one.
    UV = vertexUV;
}

To:

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in float vertexPosition_modelspace[3];
layout(location = 1) in vec2 vertexUV;

// Output data ; will be interpolated for each fragment.
out vec2 UV;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main(){

    // Output position of the vertex, in clip space : MVP * position
    gl_Position =  MVP * vec4(vertexPosition_modelspace[0], vertexPosition_modelspace[1], vertexPosition_modelspace[2], 1);
    
    // UV of the vertex. No special space for this one.
    UV = vertexUV;
}

The cube isn't displayed correctly. I can see that passing arrays of floats to the vertex shader and accept them there as vec3 works, but what is wrong using float[3] as the type to pass arrays of floats or how is this to be done?

Isn't float[3] equal to vec3?

Furthermore I'm somewhat surprised, that writing the following line in variants:

layout(location = 0) in float[] vertexPosition_modelspace;

layout(location = 0) in float[3] vertexPosition_modelspace;

layout(location = 0) in float vertexPosition_modelspace[3];

Seems to compile and at least to run, without proper display, however.

1
Why you don't want to use vec3 in the shader code. (vec3 supports extended features compared to float[3].) That doesn't prevent you to bind a float[] on CPU/C++ side for this attribute. (You even could bind a float[][3] array in C++ though I'm afraid to earn complaints from C++ purists concerning this.)Scheff's Cat
@RichardCritten No, that is a completely different issue. This question is about the vertex shader interface. The link is about SSBO and UBO.Rabbid76
"Isn't float[3] equal to vec3?" No it isn't.derhass

1 Answers

4
votes

The declaration:

layout(location = 0) in float vertexPosition_modelspace[3];

specifies that the array of float is distributed throughout the 3 consecutive layout locations, beginning at the location 0, specified in layout(location = 0).

So, the array values:

vertexPosition_modelspace[0], vertexPosition_modelspace[1], vertexPosition_modelspace[2]

are distributed respectively throughout layout locations from 0 to 2.

Then, the next declaration:

layout(location = 1) in vec2 vertexUV;

causes overwriting of the preceding array data at location = 1, resulting in deformations.

Therefore, to avoid this, you would need to either: declare the array last in the layout:

layout(location = 1) in float vertexPosition_modelspace[3];
layout(location = 0) in vec2 vertexUV;

or declare the other variable at location = 3, after the end of the preceding array:

layout(location = 0) in float vertexPosition_modelspace[3];
layout(location = 3) in vec2 vertexUV;