OpenGL 4.5 - 着色器存储:在顶点着色器中写入,在片段着色器中读取

时间:2017-08-01 21:03:12

标签: fragment-shader vertex-shader opengl-4 shader-storage-buffer

我的片段和顶点着色器都包含以下两个人:

struct Light {
  mat4 view;
  mat4 proj;
  vec4 fragPos;
};

layout (std430, binding = 0) buffer Lights {
  Light lights[];
};

我的问题是最后一个字段fragPos是由顶点着色器计算的,但是片段着色器看到{{>中的顶点着色器所做的更改1}}(或任何更改):

fragPos

...其中aLight.fragPos = bias * aLight.proj * aLight.view * vec4(vs_frag_pos, 1.0); 在循环中为aLight。你可以想象我正在计算在阴影映射中使用的每个光的坐标系中顶点的位置。知道这里有什么问题吗?我做了一个根本错误的事情吗?

以下是我初始化存储空间的方法:

lights[i]

值得注意的是,如果我将struct LightData { glm::mat4 view; glm::mat4 proj; glm::vec4 fragPos; }; glGenBuffers(1, &BBO); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, BBO); glNamedBufferStorage(BBO, lights.size() * sizeof(LightData), NULL, GL_DYNAMIC_STORAGE_BIT); // lights is a vector of a wrapper class for LightData. for (unsigned int i = 0; i < lights.size(); i++) { glNamedBufferSubData(BBO, i * sizeof(LightData), sizeof(LightData), &(lights[i]->data)); } 移动到顶点着色器fragPos中的固定大小数组out变量,请将结果保留在那里,然后添加片段着色器对应项out fragPos[2]并将其用于我的其余部分然后就可以了。所以我想知道的更多关于为什么我的片段着色器看不到顶点着色器压缩的数字。

1 个答案:

答案 0 :(得分:2)

我不会很准确,但我会尝试解释为什么你的片段着色器看不到你的顶点着色器写的是什么:

当您的顶点着色器在缓冲区内写入一些信息时,您编写的值不是必须在视频内存中写入,而是可以存储在一种缓存中。当片段着色器读取缓冲区时,会出现相同的想法,它可能会读取缓存中的值(与顶点着色器不同)。

要避免此问题,您必须做两件事,首先,您必须将缓冲区声明为连贯的(在glsl中):layout(std430) coherent buffer ...

一旦你有了这个,在你写完之后,你必须发出一个障碍(全局,它说:小心,我在缓冲区内写入值,你会读到的值可能无效,请采取我写的新值)。

怎么做这样的事情? 写入后使用函数memoryBarrierBufferhttps://www.khronos.org/registry/OpenGL-Refpages/gl4/html/memoryBarrierBuffer.xhtml

顺便说一下:在投射之后别忘了除以w。