У меня следующий поток рендеринга:
- Очистить цветное приложение MSAA x8 FBO (RGBA) с
{0.0f,0.0f,0.0f,0.0f}
- Выпуск одиночного вызова отрисовки (рисование прямоугольной формы).
- Find Resolve FBO (только одно цветное вложение RGBA)
- Переведите 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 альфа очищены до нуля:
Blit результаты с MSAA FBO альфа очищены до одного:
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 очищено до нуля:
MSAA FBO очищено до одного:
Я также не вижу никаких изменений, даже если я отключил смешивание с glDisable(G_BLEND)