#opengl #glsl #vertex-shader
#opengl #glsl #вершинный шейдер
Вопрос:
В настоящее время я изучаю OpenGL с шейдерами (3.3). Однако есть одна вещь, с которой я, похоже, не могу разобраться. Я читал, что использование встроенных переменных, таких как gl_Position и gl_FragCoords, устарело в OpenGL 3 , поэтому я хотел использовать свою собственную выходную переменную.
Итак, вместо этого:
#version 330n
layout(location=0) in vec2 i_position;
out vec4 o_position;
void main()
{
gl_Position = vec4(i_position, 0.0, 1.0);
};
Я написал это:
#version 330n
layout(location=0) in vec2 i_position;
out vec4 o_position;
void main()
{
o_position = vec4(i_position, 0.0, 1.0);
};
Шейдеры компилируются без проблем в обоих случаях, но второй код выдает просто пустой экран. Нужно ли мне как-то указывать, какая переменная является выходной?
Комментарии:
1. Ни одна из этих встроенных переменных не рекомендуется. До появления основных профилей (профилей совместимости) были встроенные модули, отражающие фиксированные атрибуты конвейера, такие как
gl_Color
,gl_Normal
, и т.д.2. О, тогда я сожалею. Я читал, что некоторые
gl_*
переменные устарели, и думал, что все они были. Спасибо за разъяснение. В любом случае, как мне заставить его работать с пользовательской выходной переменной? Или вы просто используете атрибут gl_Position для установки положения вершины?3. Вы все равно должны использовать
gl_Position
. Эта переменная является специальной, поскольку она определяет координаты, которые используются фиксированными функциональными блоками между вершинными и фрагментными шейдерами (отсечение, растеризация и т. Д.). Вы не можете заменить его определенной вами переменной. В дополнение к примерам, о которых уже упоминал @BrettHale,gl_FragColor
, который раньше был предопределенным выводом фрагментного шейдера, также устарел.4. Я понимаю. Я думал, что если вы можете указать пользовательские выходные данные во фрагментном шейдере, вы можете сделать это в вершинном шейдере, по-видимому, я ошибался. Еще раз спасибо за разъяснение. Мне еще многому предстоит научиться, но пока OpenGL доставляет огромное удовольствие.
5. Вы можете это сделать, но
gl_Position
это частьgl_PerVertex
. Точнее, это необязательная часть, все еще существуют части конвейера рендеринга с фиксированной функцией, которые требуютgl_PerVertex.gl_Position
.gl_FragCoord
, как вы упомянули, фактически вычисляется из этой переменной — после деления наw
и преобразования области просмотра.
Ответ №1:
Это было в основном рассмотрено в комментариях, но в интересах получения ответа позвольте мне обобщить, какие предопределенные переменные GLSL исчезли в основном профиле, а какие все еще существуют.
В большинстве случаев предопределенные переменные были удалены из шейдеров основного профиля как прямое следствие удаления больших частей конвейера фиксированных функций из API. Было много uniform
переменных, которые отражали состояние, которого просто больше не существует. Типичные примеры включают:
- Исправлено состояние преобразования функции (
gl_ModelViewMatrix
,gl_ProjectionMatrix
, и т.д.). - Параметры освещения (
gl_Light*
). - Параметры материала (
gl_Material*
). - Обрезать плоскости (
gl_Clip*
).
Аналогично, входные данные вершинного шейдера, получившие атрибуты вершин фиксированной функции, исчезают, поскольку в основном профиле поддерживаются только общие атрибуты. К ним относятся gl_Vertex
, gl_Normal
, gl_Color
, и т.д.
Также использовались некоторые предопределенные varying
переменные, такие как gl_FrontColor
, gl_BackColor
, и gl_TexCoord
которые все исчезли, и их можно легко заменить, определив ваши собственные out
/ in
переменные.
Также исчезли предопределенные выходные данные шейдера фрагментов gl_FragColor
и gl_FragData
. Это интересный случай, поскольку причина не в устаревании функции. Я понимаю, что они устарели, потому что они были недостаточно гибкими для обеспечения текущей функциональности. Поскольку тип gl_FragColor
was vec4
, выходные данные фрагментного шейдера должны быть векторами с компонентами с плавающей запятой. Это плохо работает, если ваша цель рендеринга имеет другой тип, например, если вы рендерите текстуру с целым числом.
Итак, какие предопределенные переменные все еще остались? Хотя их намного меньше, чем раньше, их все еще несколько, и все они относятся к фиксированной функции, которая все еще существует в программируемом конвейере. Примеры включают:
- Интерфейс координат вершин между вершинным шейдером и фрагментным шейдером, который в основном состоит из
gl_Position
вывода в вершинном шейдере иgl_FragCoord
ввода в фрагментном шейдере. Между вершинными и фрагментными шейдерами все еще есть ряд фиксированных функциональных блоков, таких как обрезка и растеризация. Эти фиксированные функциональные блоки работают с координатами вершин, поэтому предопределенные переменные по-прежнему имеют смысл. - Некоторые переменные, связанные с созданием экземпляра (
gl_VertexID
,gl_InstanceID
) . gl_ClipDistance
для поддержки отсечения произвольными плоскостями, которое также все еще присутствует в форме фиксированной функции.gl_FrontFacing
. Порядок намотки треугольников оценивается фиксированной функцией и становится доступным для шейдера фрагментов.
Ни один из этих списков не является исчерпывающим, но я надеюсь, что это полезный обзор и дает некоторую информацию. Как всегда, документы спецификации предоставляют окончательный и полный ответ.
Комментарии:
1. Спасибо всем за их ответы, они действительно многое прояснили для меня. OpenGL — довольно сложный API, поэтому многие вещи поначалу не очевидны.
Ответ №2:
Как только что сказал наш коллега, gl_Position не является устаревшим. Я только что купил книгу OpenGL Superbible 6th edition об OpenGL 4.3 и прямо на первых страницах (стр. 18) используется эта функция.
Я могу только рекомендовать получить книгу. Он написан людьми, разрабатывающими OpenGL, и он действительно дидактический.
Я тоже был потерян, как и вы, раньше, потому что я пытался учиться через Интернет или stackexchange, и после того, как я получил эту книгу, я прекрасно провожу время с OpenGL. Я думаю, что то, что я узнаю через три недели с книгой, будет более ценным, чем 5 лет обучения в Интернете. OpenGL не сложен и не является каким-то «чудовищем», как говорят многие, пока вы изучаете его из этой книги. Если вы изучите это через Интернет, я уверен, что это больше, чем зверь!
В этой книге с самого начала говорится, что он не собирается учить чему-либо, что не является основным OpenGL, поэтому вы можете быть уверены, что не попадете в ловушки, подобные той, которую вы сделали.
Вы можете купить эту книгу, использованную в Amazon, всего за 50 центов. Я могу только рекомендовать это!
Комментарии:
1. Я думаю, что он сделал, если первое предложение. И затем подтвердилось то, что я подозревал, Интернет не является исчерпывающим ресурсом для понимания того, что происходит с шейдеризованными версиями OpenGL. Что является позором, поскольку в OpenGL есть wiki.