Кроме того, у нас есть предопределенный gl_FragColor.
Начнем с этого. Нет, у вас нет предопределенного gl_FragColor
. Это было удалено из ядра OpenGL 3.1 и выше. Если вы не используете совместимость (в этом случае шейдеры 3.30 должны указывать #version 330 compatibility
вверху), вам никогда не следует ее использовать.
Теперь вернемся к пользовательским выводам фрагментного шейдера. Но сначала небольшая аналогия.
Помните, как в вершинных шейдерах у вас есть входы? И эти входы представляют собой вершину индексов атрибутов, число Проходите glVertexAttribPointer
и glEnableVertexAttribArray
так далее? Вы устанавливаете, какой вход будет извлекаться из какого атрибута. В GLSL 3.30 вы используете этот синтаксис:
layout(location = 2) in color;
Это устанавливает, что color
ввод вершинного шейдера будет поступать из местоположения атрибута 2. До 3.30 (или без ARB_explicit_attrib_location) вам нужно было бы явно установить это с помощью glBindAttrbLocation
перед связыванием или запросить программу для индекса атрибута с glGetAttribLocation
. Если вы явно не укажете местоположение атрибута, GLSL назначит местоположение произвольно (то есть: способом, определяемым реализацией).
Установка его в шейдере почти всегда лучший вариант.
В любом случае выходные данные фрагментного шейдера работают почти так же. Фрагментные шейдеры могут записывать в несколько выходных цветов , которые сами отображаются на несколько буферов в буфере кадра . Следовательно, вам нужно указать, какой вывод идет на какой цвет вывода фрагмента.
Этот процесс начинается со значения местоположения вывода фрагмента. Это очень похоже на расположение входных данных вершинного шейдера:
layout(location = 1) out secColor;
Также существуют функции API glBindFragDataLocation
и glGetFragDataLocation
, аналогичные glBindAttribLocation
и glGetAttribLocation
.
Если вы не выполняете каких-либо явных назначений, реализации обычно присваивают одну из ваших выходных переменных местоположению 0. Однако стандарт OpenGL не требует такого поведения, поэтому вы также не должны зависеть от него.
Теперь , чтобы быть справедливым, ваша программа должна не удалось в связи , когда вы использовали два выхода, которые не получают в разных местах выхода. Вероятно, произошло то, что ваш компилятор оптимизировал тот, для которого вы не писали, поэтому он как бы забыл об этом, когда пришло время проверять ошибки компоновщика.
gl_FragColor
отказались от рекомендаций в пользу предоставления вам большей гибкости в выборе буфера для записи? Имеет смысл. Еще раз спасибо!layout (location = 0) out vec4 outColor
при рисовании к чему-то привязанному (чаще всего «экран», а не FBO). Итак, по умолчанию, если мы не связали FBO (или другой буфер) с помощью glDrawBuffers и укажемlocation = 0
, он всегда будет правильно отображаться на экране?Я хотел бы указать это для OpenGLES 3.1, который использует ссылку GLSL_ES_3.10 :
источник