У меня есть структура PointLight на С++.
struct PointLight
{
glm::vec4 position; // 16 bytes
glm::vec4 color; // 16 bytes
float intensity; // 4 bytes rounded to 16 bytes?
float range; // 4 bytes rounded to 16 bytes?
};
использование в ssbo:
layout(std430, binding = 3) buffer lightSSBO
{
PointLight pointLight[];
};
Будут ли элементы с плавающей точкой округляться до 16 байт из-за vec4? Всегда ли std430 округляет элементы массива до размера самого большого элемента?
Нужно ли мне добавлять дополнения к моей структуре для правильного доступа к переменным?
struct PointLight
{
glm::vec4 position; // 16 bytes
glm::vec4 color; // 16 bytes
float intensity; // 4 bytes
float range; // 4 bytes
float padding[2]; // padding to make struct multiple of 16 bytes, because
// largest element vec4 is 16 bytes
// total 48 bytes
};
Да. (см. https://registry.khronos.org/OpenGL/specs/gl/glspec46.core.pdf#page=166&zoom=100,168,308) из правила 9 и 10 для std430
: если элемент представляет собой массив S-структур , базовое выравнивание структуры равно N, где
N — это наибольшее значение базового выравнивания любого из его членов.
В случае std140
это значение будет округлено до базового выравнивания vec4
. I случай std430
не округляется в большую сторону. Однако, поскольку самый большой элемент в вашем случае — это vec4
, в вашем случае это не имеет значения.
@Dave Для std140
округляется до vec4
. В случае std430
оно не округляется в большую сторону. Но в вашем случае элемент largest
уже vec4
.
То есть для массива std430 всегда округляется до наибольшего элемента?
@Dave Да, как ясно указано в спецификации.
Ах я вижу. Спасибо за разъяснение. Я не очень хорошо разбираюсь в характеристиках
Как это не имеет значения, если правило не применяется к std430?