Искажающие артефакты при прозрачном разрешении MSAA FBO - PullRequest
0 голосов
/ 29 апреля 2019

У меня следующий поток рендеринга:

  1. Очистить цветное приложение MSAA x8 FBO (RGBA) с {0.0f,0.0f,0.0f,0.0f}
  2. Выпуск одиночного вызова отрисовки (рисование прямоугольной формы).
  3. Find Resolve FBO (только одно цветное вложение RGBA)
  4. Переведите MSAA FBO в Resolve FBO.

Что я заметил, что когда я очищаю FBO MSAA для всех нулей, у AA все еще есть некоторые артефакты сглаживания вдоль диагональных краев. Но если я уберу с {0.0f,0.0f,0.0f,1.0f}, сглаживание выглядит нормально. Чтобы убедиться, что проблема связана с альфа-каналом, я прикрепил цветную текстуру для разрешения FBO, имеющего формат GL_RGB вместо GL_RGBA (аналогично разрешению в экранный кадровый буфер, который не показывает эту проблему), и в этом случае проблема не появляются.

Итак, мой вопрос: почему это происходит, когда MSAA RT очищается с нулевой альфа? И как я могу решить это, кроме очистки альфа в один? Зачем мне это очищать до нуля? Потому что это промежуточный проход, результаты которого используются позже в альфа-композиции.

Вот некоторые важные части кода. Я опускаю чистую логику инициализации OpenGL для текстур и настройки FBO, поскольку она абстрагирована от C ++ API, который хорошо протестирован в производстве. Оба FBO используют текстурные вложения формата RGBA.

Цикл рендеринга:

 const float clearColorZero[4] = { 0.0f,0.0f,0.0f,0.0f };

 glClearNamedFramebufferfv(msaaFBO, GL_COLOR, 0, clearColorZero);
 glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
 glViewport(0, 0,width,height);
 //Bind shader program and mesh:
 BindProgram(mainProg);
 BindMesh(mesh);
 glProgramUniformMatrix4fv(mainProg, 0, 1, GL_FALSE,glm::value_ptr(matrixMVP)); 
 Draw(mesh);//calls glDrawArrays

 //Resolve MSAA
 glBlitNamedFramebuffer(
                msaaFBO,
                resolveFBO, 
                0, 0, width, height,
                0, 0, width, height,
                GL_COLOR_BUFFER_BIT,GL_NEAREST);

Простой фрагментный шейдер:

 #version 450 core
 out vec4 o_color;
 void main()
 {
    o_color = vec4(1.0,228.0 /255.0,123.0/255.0,1.0); 
 }

Blit результаты с MSAA FBO альфа очищены до нуля:

enter image description here

Blit результаты с MSAA FBO альфа очищены до одного:

enter image description here

PS: То же самое происходит, если я разрешаю MSAA вручную внутри шейдера:

#version 450 core
#define NUM_MSAA_SAMPLES 8
layout(binding  = 0) uniform  sampler2DMS colorMap;
out vec4 o_color;
void main()
{
     vec4 color = texelFetch(colorMap,ivec2(gl_FragCoord.xy), 0);
     for(int i = 1; i < NUM_MSAA_SAMPLES; ++i)
     {
        vec4 samplePoint = texelFetch(colorMap, ivec2(gl_FragCoord.xy), i);
        color += samplePoint; 
     }
     color /= float(NUM_MSAA_SAMPLES); 
     o_color= color;
}

Вот увеличенная версия скриншотов, на которой показано:

MSAA FBO очищено до нуля:

enter image description here

MSAA FBO очищено до одного:

enter image description here

Я также не вижу никаких изменений, даже если я отключил смешивание с glDisable(G_BLEND)

...