OpenGL 统一 nof 发现如果统一块变得太大



我正在尝试实现一个统一块。

这是我的片段着色器中块的外观:

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

问题

OpenGL将统一数组的大小限制为MAX_VERTEX_UNIFORM_COMPONENTS_ARB。 据我所知,这通常设置为 2048 或 4096,因此分别是 512 或 1024 字节的限制。(这取决于图形硬件)
一个 Light 对象当前使用 84 字节的数据。
问题是当您创建一个包含 32 个这些对象的数组时,该数组会占用 2688 字节的数据。
6 号工作的原因是 84*6 是 504,即 512 <。

修复

不幸的是,根据我的研究,这个限制似乎是由硬件强加的,除非您切换到具有不同限制的显卡(或者可能通过创建自定义图形驱动程序来更改 OpenGL 实现),否则无法更改它。解决问题的最简单方法是 减小光源阵列的大小或减小光源对象的大小(或两者的组合)。

编辑:谢谢BDL使用UBO或SSBO的出色建议。他是对的,这些将允许您通过更大的制服。我还编辑了我的答案,以反映MAX_VERTEX_UNIFORM_COMPONENTS的真正定义。

@bitQUAKE想出了一个使用不同大小限制的解决方法:
查看下面的评论以获取他的解决方案。以下是有关该主题的相关讨论。

最新更新