如果统一块太大,则发现OpenGL uniform nof

时间:2017-06-16 12:33:16

标签: opengl glsl buffer shader uniform

我正在尝试实施统一块。

这就是我的片段着色器中块的样子:

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作为统一位置)。

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是关于该主题的相关讨论。