2015-08-16 5 views
1

Я пытаюсь выяснить, как SSBO работает с очень простым примером. Вершинные шейдеры:Trivial OpenGL Shader Storage Buffer Object (SSBO) не работает

#version 430 

layout(location = 0) in vec2 Vertex; 

void main() { 
    gl_Position = vec4(Vertex, 0.0, 1.0); 
} 

И пиксельный шейдер:

#version 430 

layout(std430, binding = 2) buffer ColorSSBO { 
    vec3 color; 
}; 

void main() { 
    gl_FragColor = vec4(color, 1.0); 
} 

Я знаю, что они работают, потому что, если я заменю vec4(color, 1.0) с vec4(1.0, 1.0, 1.0, 1.0) я вижу белый треугольник в центре экрана.

Я инициализировать и связать SSBO со следующим кодом:

GLuint ssbo; 
glGenBuffers(1, &ssbo); 
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); 
float color[] = {1.f, 1.f, 1.f}; 
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*sizeof(float), color, GL_DYNAMIC_COPY); 
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo); 
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 

Что здесь не так?

+2

Ваши флаги использования кажутся мне немного странными, хотя я никогда в них не верил. Вы сказали GL, что этот буфер будет заполнен данными, которые вы копируете из какого-то другого буфера, но ... при распределении буфера вы заполняете его данными из самого клиента. Я давно считал эти намеки плацебо, но вы никогда не знаете - это может быть первый в мире водитель, который буквально принимает эти намеки? :) Пробовали ли вы более логичный подсказку «GL_DYNAMIC_DRAW»? –

+2

Если вы попытаетесь расширить этот SSBO в массив, вы столкнетесь с проблемой выравнивания. Вам нужно будет изменить 'color' на' vec4' или поместить 'float' сразу после него. Я уверен, что вы это знаете. –

+0

Идея состоит в том, чтобы использовать этот буфер для реализации независимой прозрачности порядка с независимым списком, поэтому он будет записан, а затем прочитан только с помощью флеш-шейдеров, но тем временем я тестирую его с данными хоста. Я попробовал оба ваших предложения, но то, что я вижу, по-прежнему является черным экраном :(Очень расстраивает. – Shepard

ответ

1

При рисовании треугольника необходимы три точки, а для каждой точки требуются 3 отдельных набора красных зеленых синих значений. Вы помещаете только один набор в буфер шейдера. Для двух других точек значение цвета падает до значения по умолчанию, которое является черным (0,0,0,0,0,0). Если у вас нет включенного смешивания, вполне вероятно, что треугольник будет полностью окрашен в черный цвет, потому что две его вершины черные.

Попробуйте добавить еще 2 набора красно-зеленых синих значений в буфер хранения, чтобы увидеть, как они будут загружать их в качестве значений цвета для двух других точек.

0

Я предполагаю, что вам не хватает привязки SSBO до рендеринга. В вашем примере вы копируете содержимое, а затем связываете его немедленно, что необязательно для объявления. Другими словами, следующая строка в вашем примере:

... 
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo); 
... 

должны быть помещены перед визуализацией, такие как:

... 
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo); 

/* 
Your render calls and other bindings here. 
*/ 

glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 
... 

Без этого, ваш шейдер (теоретически) не будет иметь возможность видеть содержимое ,

Кроме того, как предположил Andon M. Coleman, вы должны использовать отступы для своих элементов при объявлении массивов (например, использовать vec4 вместо vec3). В противном случае это, по-видимому, будет работать, но приведет к появлению странных результатов из-за этого факта.

Следующие две ссылки помогли мне понять смысл в SSBO и как обрабатывать их в вашем коде:

https://www.khronos.org/opengl/wiki/Shader_Storage_Buffer_Object http://www.geeks3d.com/20140704/tutorial-introduction-to-opengl-4-3-shader-storage-buffers-objects-ssbo-demo/

Я надеюсь, что это помогает кому-либо сталкивается с подобными проблемами!

P.S .: Я знаю, что это сообщение устарело, но я хотел внести свой вклад.