Делаем буфер позиции для отложенного рендера - шум в генерируемых текстурах

Я пытаюсь реализовать отложенное затенение в первый раз, но у меня возникают проблемы с созданием буферов. Я начал пытаться сделать только буфер позиции, поэтому вот относительный код:

glGenFramebuffers(1, &gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);

glGenTextures(1, &gPosition);
glBindTexture(GL_TEXTURE_2D, gPosition);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT,
    NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0);
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1024, 1024);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;


glBindFramebuffer(GL_FRAMEBUFFER, 0);

Фреймбуфер успешно заполнен и переходим к основному циклу:

glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glActiveTexture(gPosition);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, 1024, 1024);
mat4 modelMatrix = mat4(1);
glUseProgram(gShader);
glUniformMatrix4fv(mgLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glUniformMatrix4fv(pgLoc, 1, GL_FALSE, &projectionMatrix[0][0]);
glUniformMatrix4fv(vgLoc, 1, GL_FALSE, &viewMatrix[0][0]);
glBindVertexArray(objVAO);
glDrawArrays(GL_TRIANGLES, 0, objVertices.size());
glBindFramebuffer(GL_FRAMEBUFFER, 0);

А это фрагментный шейдер:

layout (location=0) out vec3 gPosition;
in vec3 vertex_world;
out vec4 FragColor;

void main()
    {

     FragColor=vec4(vertex_world,1.0);


    }

Буфер позиций выглядит нормально:

введите здесь описание изображения

Однако, если вы посмотрите на мой шейдер, я не придал значение gPosition. Похоже, что буфер просто принимает вывод fragColor.

Это то, что я планирую сделать, но это дает мне неправильные результаты:

layout (location=0) out vec3 gPosition;
in vec3 vertex_world;


void main()
{

     gPosition=vertex_world;


}` 

Он что-то передает в буфер позиций, но вы увидите, что это довольно странно: введите здесь описание изображения

Что может быть не так?

Изменить/решено

Получается, что мне пришлось определить gPosition как vec4 во фрагментном шейдере. Теперь он работает отлично. Итак, новый вопрос: почему это сработало сейчас?


person John Katsantas    schedule 25.12.2018    source источник
comment
В качестве примечания: сохранение позиции в g-буфере — это пустая трата пропускной способности памяти. Все, что нужно, — это буфер глубины (который вы все равно хотите использовать), и вы можете позже восстановить 3D-позицию в любом соответствующем пространстве из глубины и позиции 2D-экранного пространства.   -  person derhass    schedule 26.12.2018


Ответы (1)


glActiveTexture не берет имя текстуры, а выбирает юнит активной текстуры (GL_TEXTURE0 + n) — да, имя вводит в заблуждение.

Во всяком случае, кажется, что вы хотите привязать текстуру буфера положения перед ее рендерингом. Почему? Если вы действительно это сделали, вы можете получить цикл обратной связи – см. https://www.khronos.org/opengl/wiki/Framebuffer_Object#Feedback_Loops. У вас все в порядке, пока вы не берете сэмплы из него, но сама возможность наличия цикла обратной связи может привести к более медленному пути кода. Так что постарайтесь этого не делать. Вы привязали текстуру как вложение к FBO, этого достаточно.

Что касается рендеринга фактического буфера положения: зачем это делать? Просто используйте текстуру буфера глубины (вместо буфера рендеринга) и реконструируйте позицию по одному значению глубины и не-проекции.

person datenwolf    schedule 25.12.2018
comment
Как вы могли заметить, я понятия не имею, что делаю. Или, по крайней мере, я этого не делал, когда впервые писал это. Я точно следовал инструкциям и в какой-то момент начал перемещать вещи, надеясь, что это сработает. Ваши комментарии были очень полезны. Я думаю, что нашел, что вызывало проблемы, но я не могу понять, почему это произошло. Оказывается, во втором случае мне пришлось определить вывод как vec4. Вы знаете, почему это будет иметь такое значение? - person John Katsantas; 25.12.2018