我正在尝试实施统一块。
这就是我的片段着色器中块的样子:
struct Light {
uint LightType;
vec3 Direction;
float SpotBlur;
vec3 AmbientColor;
float LinearAttenuation;
vec3 DiffuseColor;
float QuadraticAttenuation;
vec3 SpecularColor;
float CubicAttenuation;
vec3 Position;
float SpotCutoff;
};
layout(std140) uniform LightBlock
{
Light values;
} lights[32];
正如你所看到的,我定义了一个固定大小为32的Light结构数组。我可以毫无问题地上传数据,但现在我不明白了。 如果“灯”阵列的尺寸相对较小(约为6),那么我的所有着色器制服都会被找到。但是当增加“灯”尺寸时,它开始有点覆盖我的制服。例如,它无法再从顶点着色器中找到我的“modelViewProjection”矩阵(返回-1作为统一位置)。
答案 0 :(得分:1)
OpenGL通过MAX_VERTEX_UNIFORM_COMPONENTS_ARB限制统一数组的大小。
从我所看到的,这通常设置为2048或4096,因此分别为512或1024字节限制。 (它取决于图形硬件)
One Light对象目前使用84字节的数据。
问题是当您创建一个包含32个这些对象的数组时,这些对象使用了2688字节的数据。
尺寸为6的原因是因为84 * 6是504,所以< 512。
不幸的是,根据我的研究,似乎这个限制是由硬件强加的,除非你切换到具有不同限制的图形卡(或者可能通过创建自定义图形来改变OpenGL实现),否则无法更改它驱动程序)。解决问题的最简单方法是
减小灯光阵列的大小或减小灯光对象的大小(或两者的组合)。
编辑:谢谢BDL关于使用UBO或SSBO的优秀建议。他是正确的,这将允许你通过更大的制服。我还编辑了我的答案,以反映MAX_VERTEX_UNIFORM_COMPONENTS的真实定义。
@bitQUAKE提出了一种使用不同大小限制的解决方法:
请查看以下评论,了解他的解决方案。 Here是关于该主题的相关讨论。