Вывод фреймбуфера OpenGL 3.0 во вложения без моего указания?

#opengl #glsl

#opengl #glsl #вложение #фреймбуфер #фрагмент-шейдер

Вопрос:

Итак, у меня есть фреймбуфер с множеством вложений. Вложения — это цвет, цветение, скорость и глубина.

Я начинаю с очистки фреймбуфера до значений по моему выбору с помощью следующего кода.

 // Clear Color Buffer
float colorDefaultValue[4] = { 0.5, 0.5, 0.5, 1.0 };
glClearBufferfv(GL_COLOR, 0, colorDefaultValue);

// Clear Bloom Buffer
float bloomDefaultValue[4] = { 0.0, 0.0, 1.0, 1.0 };
glClearBufferfv(GL_COLOR, 1, bloomDefaultValue);

// Clear Depth Buffer
float depth[1] = { 1.0 };
glClearBufferfv(GL_DEPTH, 0, depth);
  

Затем я приступаю к рендерингу сцены с использованием моего основного шейдера.
Как вы можете видеть в приведенном ниже коде, я указал выходные данные.

 // Layouts
layout (location = 0) out vec4 o_vFragColor;
layout (location = 1) out vec4 o_vBloomColor; 
  

А затем я вывожу для них значения в шейдере фрагментов.

 o_vFragColor = vec4(color, alpha);
float brightness = dot(o_vFragColor.rgb, vec3(0.2126, 0.2126, 0.2126)); 
if(brightness > 1.0)
    o_vBloomColor = vec4(o_vFragColor.rgb, 1.0);
  

Теперь мой вопрос: если фрагмент недостаточно яркий, почему он выводит черный цвет во вложение bloom? Я не указывал, чтобы он что-либо выводил, но он все равно его настраивает.

Например, если я очищу буфер цветения до зеленого

 // Clear Bloom Buffer
float bloomDefaultValue[4] = { 0.0, 1.0, 0.0, 1.0 };
glClearBufferfv(GL_COLOR, 1, bloomDefaultValue);
  

и я не вывожу никакого значения для вложения bloom в шейдере фрагмента, я получаю черный цвет в буфере bloom. Вы можете увидеть это на следующем изображении.

BloomBuffer

Части изображения, где буфер зеленого цвета, — это те, где геометрия не была нарисована. Черные части — это части изображения, которые содержали недостаточно яркую геометрию и, следовательно, не должны были ничего выводить в буфер цветения, но они явно что-то выводили, в данном случае черное. Фиолетовые части — это фрагменты, которые превышают порог яркости и работают по назначению.

Что с черным?

Ответ №1:

Вы не можете выполнять условную запись в цветовой буфер из фрагментного шейдера.

Выходной фрагмент всегда имеет значения для каждого активного цветового буфера, даже если вы их не записывали. Это верно, даже если вы не объявляете переменную для этого выходного значения. Если в определенное местоположение вывода фрагмента не записывается значение, используемое значение будет неопределенным. Но это будет что-то.

Вы можете выполнять условную запись на основе цветовой маскировки. Но это зависит от каждого вызова, а не от того, что можно сделать в шейдере фрагментов. Вы могли бы использовать смешивание в этом цветовом буфере, используя альфа 0 для обозначения «не записывать» и альфа 1 для замены того, что там есть.