Custom attribute data at multiple shaders

Hi all,

I’m wondering what’s the best way to send custom vertex data to a shader within the mesh geometry.
Let me explain my question.

I want to draw a mesh using extra per-vertex data at the shader.
At this post by @edapx, you can find a way to add custom data into the VBO of a ofVboMesh…
But this method requires the attrib location of an attribute inside an specific shader. So those data will not work in a different shader.

For instance:

  • I do have different 2 shaders (program_01 and program_02) and a ofVboMesh. with a simple triangle.
  • I do want to add some custom color data to the triangle VBO so I can use it at the shaders.

// Locate ‘custom_color’ attribute
GLint attLoc1 = program_01.getAttributeLocation(“custom_color”); // located at 2
GLint attLoc2 = program_02.getAttributeLocation(“custom_color”); // located at 1

// set custom Vertex Color Data
mesh.getVbo().setAttributeData(attLoc1, glm::value_ptr(colorData[0]), 3, 3*3, GL_STATIC_DRAW, sizeof(glm::vec3));

This is the result:

Only one of the shaders uses correctly the data, because the custom_color data was located at the VBO using the reference to the program_01 and the same attribute has a different location at program_02.

Does it mean I do have to duplicate the custom data and set a different Vertex Attribute for each shader/location?

I’ve tried using ofShader::bindAttribute() but did not work.

program_02.bindAttribute(attLoc2, “custom_color”);

What’s the best way to add custom vertex data to a mesh and use it on multiple shaders?
Better if the solution does not involve manual handling the data binding/unbinding each time the shader begins.

Thanks for your help and greetings :slight_smile:

Hello!

I’ve been trying ofShader::setAttribute3fv() but did not work.
The idea is passing the custom vertex data to the shader by utilizing the setAttribute function. But the shader does not look like receiving the data.

In relation to the example above:

program_02.begin();
program_02.setAttribute3fv(“custom_color”, glm::value_ptr(colorData[0]), sizeof(glm::vec3));
mesh.draw();
program_02.end();

With that code, I do have the same black triangle.
Instead, if I use the ofVbo::setAttributeData function, does it work.
Bu then I run into the same issue I mention at the first port.

I am afraid that if I duplicate the Vertex Attribute (setAttributeData) each time I want to use the ofVboMesh on a different shader, the program will encounter an issue with conflicting locations for the attributes.

Please, someone give me a hand with this?
Greetings.

Use the same attribute layout in your shaders? You have to specify the layout for each shader, so I don’t see why you wouldn’t want to make it consistent across shaders, if only for sanity’s sake.

Please let me know if this is not clear

Hi @dizzy, thanks for your suggestion but that’s not the point.

I am working on a lightmapper. So at this point, I’m triangle packing the mesh geometry to generate optimal texture coordinates for the lightmap to bake the shadows on.

The mesh will then have two sets of UV textcoords. The origina ones for the textures and the lightmap ones.

For the shadow mapping and light baking, Im using a bunch of custom shaders which structures are not the same (both require different inputs). Then I would like to be able to use the that mesh with materials like ofMaterial (using postFragment) or ofxPBR which has different attribute structures.

As example:
The light-baking shader does not use the original texcoords of the mesh, but instead requires the custom generated lightmap coords.
But then, to fully render the mesh with the colors, textures and lights, The shader includes the default attributes (position, original texcoords, normals) and then, the custom generated UV coords.
So the “IN vec2 custom_texcoords;” would have a different GLint location.

Greetings.

Please, anyone has experience utilizing ofShader::setAttribute3fv() function?