Blitting FBO Color Attachments - PullRequest
       26

Blitting FBO Color Attachments

2 голосов
/ 10 марта 2020

У меня есть 2 FBO + MRT, и они имеют идентичные вложения (по 4 цветовых вложения). использование glBlitFrameBuffer работает, как и ожидалось, для буфера глубины и для one color_attachment. Однако, когда я закрываю несколько цветовых вложений, вещи go плохие. Я провел много исследований и перепробовал много разных методов, но ни один из них не работает. Я не использую renderBufferStorage, потому что мои текстуры имеют разные внутренние форматы (RGBA и RGB16F). Это звучит как похожая проблема, за исключением того, что я не использую мультисэмплинг, только MRT.

OpenGL версия 4.3

Почему: я хочу создать состояние местности предварительно - расчеты освещения, так что мне нужно только визуализировать ландшафт, если есть изменения (ie. движение камеры), а затем скопировать эти цветовые вложения в следующее FBO. Это для отложенного затенения, и FBO очень напоминает gBuffer.

Сначала я ожидал, что я должен использовать glDrawBuffers, которые я использую в начальной настройке, но нет glReadBuffers, и поэтому я предполагаю, что у меня есть нет способа связать их. Возможно, я здесь не прав, пока не эксперт =)

Исходный код написан на Golang, должен быть легко перенесен в C ++ (будет переведен, если потребуется).

ОБНОВЛЕНИЕ / РЕШЕНО: Для всех, кто столкнулся с этой проблемой. Когда вы используете glDrawBuffers () и используете вызов glDrawBuffer (), вы перезаписываете свое состояние glDrawBuffers (). Он должен быть сброшен в свое первоначальное состояние glDrawBuffers ().

Update2: для тех, кто интересуется таким методом, я могу подтвердить, что он имеет невероятные результаты производительности, если у вас есть неанимированный мир и камера не двигается так часто. Для моей цели это здорово (RTS), но для FPS-игры, такой как CS, это был бы очень плохой подход.

Добавьте следующее после блиттинга (спецификация кейса c):

var attachments = [4]uint32{gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3}
gl.DrawBuffers(4, &attachments[0])

Настройка FBO

gl.GenFramebuffers(1, &fbo.ID)
gl.BindFramebuffer(gl.FRAMEBUFFER, fbo.ID)

//setting up color attachments

gl.GenTextures(1, &fbo.Position)
gl.BindTexture(gl.TEXTURE_2D, fbo.Position)
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, windowWidth, windowHeight, 0, gl.RGB, gl.FLOAT, nil)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbo.Position, 0)

//repeated 3 times for the additional color attachments

var attachments = [4]uint32{gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3}
gl.DrawBuffers(4, &attachments[0])

gl.GenRenderbuffers(1, &fbo.DepthBuffer)
gl.BindRenderbuffer(gl.RENDERBUFFER, fbo.DepthBuffer)
gl.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT, windowWidth, windowHeight)
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, fbo.DepthBuffer)

gl.BindFramebuffer(gl.FRAMEBUFFER, 0)

А теперь к блиттингу.

gl.BindFramebuffer(gl.READ_FRAMEBUFFER, fboIn.ID)
gl.BindFramebuffer(gl.DRAW_FRAMEBUFFER, fboOut.ID)

//works as expected
gl.BlitFramebuffer(0, 0, windowWidth, windowHeight, 0, 0, windowWidth, windowHeight, gl.DEPTH_BUFFER_BIT, gl.NEAREST)

//works as expected
gl.ReadBuffer(gl.COLOR_ATTACHMENT0)
gl.DrawBuffer(gl.COLOR_ATTACHMENT0)
gl.BlitFramebuffer(0, 0, windowWidth, windowHeight, 0, 0, windowWidth, windowHeight, gl.COLOR_BUFFER_BIT, gl.LINEAR)

//fails - no errors but produces some weird occurrences. 
gl.ReadBuffer(gl.COLOR_ATTACHMENT1)
gl.DrawBuffer(gl.COLOR_ATTACHMENT1)
gl.BlitFramebuffer(0, 0, windowWidth, windowHeight, 0, 0, windowWidth, windowHeight, gl.COLOR_BUFFER_BIT, gl.LINEAR)

gl.BindFramebuffer(gl.FRAMEBUFFER, 0)

1 Ответ

1 голос
/ 10 марта 2020

glDrawBuffer(x) концептуально эквивалентно вызову GLenum bufs[1]={x}; glDrawBuffers(1, bufs). Так как состояние буфера отрисовки является частью состояния FBO, ваш блиттинг-код перезаписывает эти состояния, и если они не будут восстановлены вручную, рендеринг впоследствии не будет работать должным образом. Если вы назовете это в al oop, это может привести к неверному выводу, что проблема заключается в блиттинге, но в действительности блинтинг работает правильно, только на неправильных входных данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...