2016-05-27 4 views
1

я связала shader storage buffer к shader storage block как такТолько получить мусор из блока хранения Shader?

GLuint index = glGetProgramResourceIndex(myprogram, GL_SHADER_STORAGE_BLOCK, name); 
glShaderStorageBlockBinding(myprogram, index, mybindingpoint); 
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mybuffer) 
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, mybindingpoint, mybuffer, 0, 48); 
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, 48, &mydata); 

mydata, указывает на std::vector, содержащей 4 glm::vec3 объекты.

Потому что я связал 48 bytes в качестве буфера Я ожидаю lights[] на хранение 48/(4*3) = 4 vec3s.

layout(std430) buffer light { 
    vec3 lights[]; 
}; 

Элемент с индексом 1 в моем std::vector содержит данные x=1.0, y=1.0, z=1.0.

Но просмотрев вывод, делая

gl_FragColor = vec4(lights[1], 1.0); 

Я вижу желтые (x=1.0, y=1.0, z=0.0) пикселей. Это не то, что я загрузил в буфер.

Может ли кто-нибудь сказать мне, что я делаю неправильно?

РЕДАКТИРОВАТЬ

Я просто changend блок хранения шейдер

layout(std430) buffer light { 
    float lights[]; 
}; 

и выход

gl_FragColor = vec4(lights[3],lights[4],lights[5],1.0); 

и он работает (белые пиксели).

Если кто-нибудь может это объяснить, это все равно будет здорово.

+0

Просьба показать точное определение mydata – deniss

ответ

4

Это потому, что люди не принимают этот простой совет: never use a vec3 in a UBO/SSBO.

Базовое выравнивание vec3 составляет 16 байт. Всегда. Поэтому, когда он массив, шаг массива (количество байтов от одного элемента к другому) всегда 16. Точно так же, как vec4.

Да, std430 макет отличается от std140. Но это не так. В частности, это только предотвращает округление базы и перемещение элементов массива (и выравнивание базы структур) до округления до vec4. Но так как выравнивание базы vec3 равно всегда, равное vec4, ничего не меняется. Он влияет только на скаляры и vec2.

+0

Я буду помнить ваш совет на всю оставшуюся жизнь. – mak

Смежные вопросы