如何在计算着色器中修改顶点的特定属性

时间:2018-07-25 10:14:26

标签: c opengl glsl

我有一个包含6值的缓冲区,前三个是位置,其他三个是顶点的颜色。我想在计算着色器中修改这些值,但只修改位置,而不修改颜色。我通过使用“图像加载/存储”实现了这一点,但是我使用了所有顶点数据,而不仅是其中一部分(一个属性)。因此,基本上我不知道如何在计算着色器中仅获取一个属性,然后对其进行修改,然后将其写回到缓冲区。


这是用于一个(且仅)属性的代码。

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);
}

那么,如何仅将部分顶点数据存储到pos中,而不是将所有属性存储?如何在pos中指定什么属性?而且,如果我将imageStore的某些特定属性返回到缓冲区,我确定只有缓冲区的那一部分会被更改(我要修改的属性)而其他属性将保持不变吗?

1 个答案:

答案 0 :(得分:2)

glVertexAttribPointer()之类的函数定义的顶点阵列状态仅在使用图形管线进行绘制时才有意义。它定义了从缓冲区元素到输入顶点属性的映射。在计算模式下没有任何作用。

由您自己定义顶点缓冲区的布局,并据此设置顶点数组。因此,您必须知道在缓冲区中的哪个位置才能找到哪个属性的哪个组件。如果您不这样做,那么您也将永远无法使用缓冲区绘制任何东西。

我不确定为什么您选择使用图像加载/存储来访问计算着色器中的顶点数据。我建议将其绑定为shader storage buffer。假设您的缓冲区仅包含一堆浮点数,则最简单的方法可能是将其解释为您的计算着色器中的浮点数数组:

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

然后,您可以像其他任何数组一样,通过普通索引在计算着色器中以vertex_data[i]的形式访问缓冲区中的第i个浮点数。

除了所有这些之外,我还应该指出,上面代码中的glVertexAttribPointer()调用只为包含4个浮点数的一个顶点属性设置了缓冲区,而不是为每个3个浮点数的两个属性设置了缓冲区。