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

Я пытаюсь включить мулисэмплинг и альфа-покрытие для 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 никогда не жалуется Я пытался возиться с этим, но у меня либо черный экран, либо экран, полный мусорных пикселей.

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

26

Решение

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

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


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

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

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

25

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]