У меня есть следующий равномерный буфер:
layout(std140) uniform Light
{
vec4 AmbientLight;
vec4 LightIntensity;
vec3 LightPosition;
float LightAttenuation;
};
У меня есть некоторые проблемы при буферизации данных и заполнения, которые мне нужно добавить. Я прочитал http://ptgmedia.pearsoncmg.com/images/9780321552624/downloads/0321552628_AppL.pdf в котором говорится, что я должен добавить дополнительные 4 байта в конце vec3 для заполнения — так что я буду загружать в общей сложности 13 байтов для ‘Light’. Однако, когда я делаю это, LightAttenuation получает значение, добавленное мной к LightPosition, а не на один байт вперед, поэтому я получаю правильные значения в шейдере, когда НЕ добавляю. Почему это?
Подробности смотрите в разделе 7.6.2.2 спецификации OpenGL, но в основном, std140
layout говорит о том, что каждая переменная будет размечена сразу после предыдущей переменной с добавлением достаточного количества отступов для выравнивания, требуемого для типа переменной. vec3
а также vec4
оба требуют 16-байтового выравнивания и имеют 12 и 16 байтов соответственно. float
требует выравнивания 4 байтов и имеет размер 4 байта. Так с std140
планировка, LightPosition
получит 16-байтовое выравнивание, поэтому всегда будет заканчиваться адресом, равным 12 mod 16. Поскольку это 4-байтовое выравнивание, дополнительный заполнитель не будет вставлен перед LightAttenuation
,
Обычно да, openGL будет рассматривать vec3 как vec4. Но AFAIK в этом случае добавляет плавающую LightAttenuation к vec3 LightPosition, формируя общий vec4 (своего рода оптимизация, выполняемая компилятором glsl).
Вся структура будет иметь размер 3x vec4.
Попробуйте использовать vec3 или vec4 для LightAttenuation.