Подтвердить что ты не робот

Как использовать мультисэмплинг с FBO OpenGL

Я пытаюсь включить mutlisampling и alpha-to-coverage для FBO. Используя фреймбуфер по умолчанию, мне нужно только позвонить glEnable(GL_MULTISAMPLE) и glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE). Тем не менее, я не могу добиться такого же эффекта, используя свой собственный FBO.

Моя цель: Нарисуйте сцену в FBO так же, как она будет обращена к фреймбуферу по умолчанию с указанными выше свойствами. Оттуда я хочу иметь возможность использовать изображение в качестве текстуры для будущих проходов через шейдер.

Это работает: код для создания FBO без мультисэмплинга/альфа-охвата, 1 привязка цвета, 1 вложение глубины:

// Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,defaultColorAttachment0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,screenWidth,screenHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);

// Bind the texture to the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, defaultColorAttachment0,0);

// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer);

Это не работает. Код, пытающийся сделать многозадачное FBO:

// Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, defaultColorAttachment0);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, screenWidth, screenHeight, GL_FALSE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, defaultColorAttachment0,0);

// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer);

Я пробовал посмотреть в вики OpenGL на этом, хотя он неполный (различные недостроенные заголовки делают его непрофессиональным). glGetError никогда не жалуется. Я пробовал общаться с этим, но я либо получаю черный экран, либо экран, полный мусорных пикселей.

Главный вопрос: Какие вещи мне нужно учитывать/изменять и где (создание FOB, текстуры, шейдеры), чтобы получить мультисэмплинг и альфа-охват для работы с FBO?

4b9b3361

Ответ 1

Вам нужно выделить многосэмплинный буфер глубины, чтобы он работал правильно и дал ему такое же количество выборок, что и ваш цветовой буфер. Другими словами, вы должны называть glRenderbufferStorageMultisample (...) вместо glRenderbufferStorage (...).

Ваше FBO должно быть не в состоянии проверить полноту проверки, как оно распределено прямо сейчас. Вызов glCheckFramebufferStatus (...) должен возвращать GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, потому что буфер глубины имеет ровно 1 образец и ваш цветной буфер приложение имеет 4.


Так как вы также используете многосэмплированную вставку текстуры в этом FBO, вы должны знать различия между выборкой однодисковой текстуры и мультисэмплированием в шейдерах GLSL.

Многосэмплированные текстуры имеют особый тип сэмплера (например, sampler2DMS), и вы должны явно извлекать каждый образец в текстуре по его целочисленной (ненормированной) тексельной координате и выборочному индексу с помощью texelFetch (...). Это также означает, что они не могут быть отфильтрованы или скопированы.

Вероятно, вам не нужна многосэмплированная текстура в этом случае, вы, вероятно, захотите использовать glBlitFramebuffer (...), чтобы разрешить MSAA в один - дискретизированный FBO. Если вы это сделаете, вы можете прочитать результаты сглаживания в ваших шейдерах вместо того, чтобы получать выборку и реализовывать сглаживание самостоятельно.