我的片段和顶点着色器都包含以下两个人:
struct Light {
mat4 view;
mat4 proj;
vec4 fragPos;
};
layout (std430, binding = 0) buffer Lights {
Light lights[];
};
我的问题是最后一个字段fragPos
是由顶点着色器计算的,如下所示,但片段着色器看不到顶点着色器在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 fragPos[2]
中的固定大小数组out
变量,将结果留在那里,然后添加片段着色器对应项in fragPos[2]
并将其用于我的其余内容,那么一切都很好。因此,我在这里想了解更多的是为什么我的片段着色器看不到顶点着色器处理的数字。
我不会很准确,但我会尝试解释为什么你的片段着色器看不到你的顶点着色器写的内容:
当顶点着色器在缓冲区中写入某些信息时,写入的值不是必须写入视频内存的,但可以存储在一种缓存中。当您的片段着色器读取缓冲区时,也会发生同样的想法,它可能会读取缓存中的值(与顶点着色器不同(。
为了避免这个问题,你必须做两件事,首先,你必须将缓冲区声明为相干的(在glsl内部layout(std430) coherent buffer ...
(:
一旦你有了它,在你写完之后,你必须发出一个屏障(全局上,它说:小心,我在缓冲区内写入值,你将读取的值可能无效,请采用我写的新值(。
怎么做这样的事情? 在写入后使用该函数memoryBarrierBuffer
。https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/memoryBarrierBuffer.xhtml
顺便说一句:不要忘记在投影后除以w。