Распутывание, когда и какие значения фиксируются при смешивании OpenGL в разных целях рендеринга

TL;DR: какие значения фиксируются и при каких обстоятельствах (включенные флаги и типы буферов рендеринга (особенно RGBA_F32)), когда включено смешивание?

  • Вывод фрагментного шейдера?
  • Факторы смешивания?
  • Результат уравнения смешивания?
  • Другие?

Механизмы, которые я нашел для зажима:

  1. Вывод шейдера (через glClampColor): похоже, он управляет glReadPixels, но есть флаги расширения GL_CLAMP_VERTEX_COLOR и GL_CLAMP_FRAGMENT_COLOR, которые делают "что-то". Насколько я могу судить из спецификации расширения, они ограничивают вывод вершинного или фрагментного шейдера.
  2. Вывод шейдера (через рендеринг в фиксированную точку): см. этот ответ, в котором цитируется спецификация GL. .: "Преобразование из значения с плавающей запятой f в соответствующее беззнаковое нормализованное значение с фиксированной точкой c определяется первым закреплением f в диапазоне [0, 1] . . ." Напротив, (предположительно, при записи в цель рендеринга с плавающей запятой) Никол Болас пишет здесь, что "Что записывается фрагментный шейдер всегда будет разблокирован.".
  3. Подразумеваемое ограничение: из документации для glBlendFunc< /a>: "Все масштабные коэффициенты имеют диапазон [0,1]." Означает ли это, что исходный и конечный коэффициенты фиксируются до того, как произойдет уравнение?
  4. Подразумеваемое ограничение: из документации для glBlendEquation< /a>: "Для этих уравнений все компоненты цвета имеют значения в диапазоне [0,1]." Означает ли это, что исходный и конечный цвета фиксируются до выполнения уравнения?
  5. Фиксация результата: с той же страницы: "Результаты этих уравнений фиксируются в диапазоне [0,1]."

В моих экспериментах с целью рендеринга RGBA_F32 ни один из этих режимов фиксации не происходит (я подтверждаю это, считывая значения из цели рендеринга с помощью glGetTexImage). Мне нужно, чтобы (3) произошло, но я прошу разъяснения по документации, чтобы я мог разобраться сам.


person imallett    schedule 10.05.2015    source источник


Ответы (1)


Часть материала, который вы процитировали, очень старая, и в этом может лежать корень путаницы. Я проанализирую ваши вопросы с точки зрения современного GL и процитирую основной профиль OpenGL 4.5 для этого. Однако ничего из этого не относится к OpenGL 4.x. Это в основном не изменилось с ядра GL 3.2.

1. Единственная оставшаяся функция glClampColor() – это зажим во время glReadPixels. Цитирование спецификации на странице 680:

Обратите внимание, что команды FrontFace и ClampColor не объявлены устаревшими, поскольку они по-прежнему влияют на другие функции, не являющиеся устаревшими; однако цели ClampColor CLAMP_VERTEX_COLOR и CLAMP_FRAGMENT_COLOR устарели."

Ограничение выходных данных вершинного шейдера имело смысл только для устаревших встроенных вариантов, таких как gl_FrontColor, gl_BackColor и так далее. Они были нужны только для имитации обработки вершин с фиксированной функцией, и их вообще никогда не было хорошей идеей. С общими выводами у GL нет возможности узнать, какие значения являются цветами, а какие нет.

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

Цитата из ответа Рето Коради из спецификации не изменилась в спецификации GL 4.5. Выходные данные шейдера будут ограничены только в том случае, если соответствующая цель рендеринга имеет формат с фиксированной точкой или целочисленный формат.

3.,4. и 5. Эти документы устарели. Спецификация GL говорит об этом в разделе 17.3.8:

Если цветовой буфер имеет фиксированную точку, компоненты исходного и целевого значений, а также коэффициенты смешивания фиксируются на [0; 1] или [-1; 1] соответственно для беззнакового нормализованного или знакового нормализованного цветового буфера до оценки уравнения смешивания. Если цветовой буфер является числом с плавающей запятой, зажима не происходит. Полученные четыре значения отправляются на следующую операцию. Смешивание применяется только в том случае, если цветовой буфер имеет формат с фиксированной или плавающей запятой. Если цветовой буфер имеет целочисленный формат, перейдите к следующей операции.

Фиксация результата смешивания происходит на следующем шаге, который обрабатывает необязательное преобразование sRGB (однако здесь этап фиксации не привязан к преобразованию sRGB). Цитирование раздела 17.3.9:

Результирующие значения cs для R, G и B, а также немодифицированный A формируют новое значение цвета RGBA. Если цветовой буфер имеет фиксированную точку, каждый компонент фиксируется в диапазоне [0; 1], а затем преобразуется в значение с фиксированной точкой с помощью уравнения 2.3. Полученные четыре значения отправляются на последующую операцию дизеринга.

Так что да, при использовании GL_RGBA32F кадрового буфера никакого неявного ограничения не происходит вообще. И на самом деле это единственный полезный режим работы для универсального случая. Если вам нужно, чтобы на шаге 3 произошла некоторая фиксация: просто зафиксируйте коэффициенты, прежде чем отправлять их на glBlendFunc().

person derhass    schedule 10.05.2015
comment
+1 и принять. Это отличный ответ и спасибо. Я все время забываю, что спецификация — гораздо лучший ресурс, чем справочные страницы; еще раз спасибо за выкапывание важных ссылок. Обратите внимание, что вы также рассмотрели (3) в разделе 4,5,6. - person imallett; 15.05.2015
comment
@imallett: О, в вопросе нет даже пункта 6 - я просто ошибся в последнем пункте. Я исправил это. - person derhass; 15.05.2015