Gavrilo Adamovic
Gavrilo Adamovic

Reputation: 2795

How to modify specific attribute of a vertex in compute shader

I have a buffer containing 6 values, the first three being position and the other three are the color of the vertex. I want to modify those values in the compute shader, but only positions, not the color. I achieved this by using Image Load/Store, but I used all vertex data, not only a part of it (one attribute). So basically I don't know how to get only one attribute in compute shader, and modify it, and write it back to the buffer.


This is the code that worked for one (and only) attribute.

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);

glGenTextures(1, &position_tbo);
glBindTexture(GL_TEXTURE_BUFFER, position_tbo);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, position_buffer);

glsl:

layout (local_size_x = 128) in;

layout (rgba32f, binding = 0) uniform imageBuffer position_buffer;

void main(void)
{
    vec4 pos = imageLoad(position_buffer, int(gl_GlobalInvocationID.x));

    pos.xyz = (translation * vec4(pos.xyz, 1.0)).xyz;

    imageStore(position_buffer, int(gl_GlobalInvocationID.x), pos);
}

So how do I store only part of the vertex data into pos, not all attributes? Where do I specify what attribute goes into pos? And if I imageStore some specific attribute back to the buffer, am I sure that only that part of the buffer will be changed (the attribute I want to modify) and other attributes will remain the same?

Upvotes: 2

Views: 1205

Answers (1)

Michael Kenzel
Michael Kenzel

Reputation: 15941

Vertex Array State defined by functions like glVertexAttribPointer() is only relevant when drawing with the graphics pipeline. It defines the mapping from buffer elements to input vertex attributes. It does not have any effect in compute mode.

It is you yourself who defines the layout of your vertex buffer(s) and sets up the Vertex Array accordingly. Thus, you necessarily know where in your buffer to find which component of which attribute. If you didn't then you couldn't ever use the buffer to draw anything either.

I'm not sure why exactly you chose to use image load/store to access your vertex data in your compute shader. I would suggest simply binding it as a shader storage buffer. Assuming your buffers just contain a bunch of floats, the probably simplest approach would be to just interpret them as an array of floats in your compute shader:

layout(std430, binding = 0) buffer VertexBuffer
{
    float vertex_data[];
};

You can then just access the i-th float in your buffer as vertex_data[i] in your compute shader via a normal index, just like any other array…

Apart from all that, I should point out that the glVertexAttribPointer() call in your code above sets up the buffer for only one vertex attribute consisting of 4 floats rather than two attributes of 3 floats each.

Upvotes: 3

Related Questions