0
votes

I need a way to pass an array to the Vertex Shader that contains multiple values for each vertex. I have this:

  • One array of 3d points
  • One array of 3d normals for each point
  • One array of faces (all triangles)
  • One array of ALL the neighborhood normals for each vertex. If vertex i has 4 neighbors, this array has 4 3d normals for the vertex (the normals of each of the 4 neighbors). For simplicity, I created this array as if all the vertex have the same number of neighbors (the maximum from the model, 4 in the next example).

So, the structure is as follows:

  • array of points = v0 v1 v2 v3 v4 ...
  • array of normals = n0 n1 n2 n3 n4 ...
  • array of faces = [0 1 2] [0 3 1] [0 4 3] ...
  • array of normals of neighborhood = [n1 n2 n3 n4] [n0 n2 n3 0] [n0 n1 0 0] [n0 n1 n4 0] [n0 n4 0 0] [n0 n3 0 0] ...

In the example, the maximum neighborhood is 4, so I fill all the normal data with 0-vectors (0.0, 0.0, 0.0) for those who don't have 4 neighbors. In the general case, I have more than 4 neighbors per vertex. In the current model, I have some vertex with 14 neighbors, thus I need 14 normals or 42 float for each vertex).

In the header of the VS, I have:

layout (location = 0) in vec3 in_Position;
layout (location = 1) in vec3 in_Normal;
layout (location = 2) in XXX in_NeighborsNormals

But I don't know what to use in XXX in order to say to the shader that the data isn't a vec3, vec4, mat4, etc., but an array of (compile-time known size) vec3.


EDIT: Maybe using a VAO isn't the way to the NeighborsNormals. I'm open to suggestions, but I need to know the specific index of the current vertex in order to access the correct values.


The goal of this is to compute the curvature of the area around the vertex, in order to tessellate using Tessellation shaders. In particular, I'm looking to replicate this work: http://perso.telecom-paristech.fr/~boubek/papers/VDTess/

I'm using C++ and OpenGL 4.0, but I could go up to OpenGL 4.3. I'm coming from a intermediate knowledge of OpenGL 2.0 but GLSL (old or modern) is new (around a few months) to me.

Thanks in advance.

1
"One array of ALL the neighborhood normals for each vertex. [...]" Can I ask exactly why you want this? This sounds like a job for geometry shaders, where if you use an adjacency primitive type you can simply extract from the vertex stream during primitive assembly.Andon M. Coleman
I need to know all the normals in order to use them in Tessellation Control Shader. Geometry shader comes after Tessellation and it won't help me :/fern17
Okay, so the important thing to understand here is that you cannot use arrays for vertex attributes. If you insist on doing it this way, you can however, do something sort of hacky - pack your array of up to 4 neighboring vec3s into a 4x4 matrix. Understand, however, that a mat4 vertex attribute takes 4 attribute slots - they are not cheap. If you want to get really fancy, you could probably use the last column of the 4x4 matrix to pack a 5th vec3 >:)Andon M. Coleman
I think you may have misunderstood what I was saying. VAOs (or more accurately, VBOs) really have nothing to do with this. You can use a mat4 vertex attribute to function as if it were an array of 4 vec4s. In fact, in many ways this is what a mat4 really is, just a fancy array of vectors. So if you want to store 4 normals per-vertex, you can do this with a mat4.Andon M. Coleman
Oh, now we are leaving the realm of practicality for storing this data per-vertex. You might consider a system of texture fetches or something along those lines.Andon M. Coleman

1 Answers

2
votes

I understand that you have some data about your objects which you want to handle it in your vertex shader. You can transfer your array to vertex shader by writing your array into a texture. After that import it in your vertex shader and use it.

in Opengl Part:

    GLuint myarray // Load your texture to this variable
glEnable(GL_TEXTURE_2D);  
glUniform1i(glGetUniformLocation(YOURSHADERID, "MYARRAY"), 0);  
glBindTexture(GL_TEXTURE_2D, myarray); //you can change the first parameter depends what type of texture you prefer.

in Vertex Shader:

    uniform sampler2D MYARRAY; // you can use sampler1D also if you upload a 1D texture 

after that you can access your data from MYARRAY.You can read from your data and form them as vec3 , vec4 whatever you want.