GLSL — использование пользовательского выходного атрибута вместо gl_Position

В настоящее время я изучаю OpenGL с шейдерами (3.3). Есть одна вещь, которую я никак не могу решить. Я читал, что использование встроенных переменных, таких как gl_Position и gl_FragCoords, не рекомендуется в OpenGL 3+, поэтому я хотел использовать свою собственную выходную переменную.

Итак, вместо этого:

#version 330\n
layout(location=0) in vec2 i_position;
out vec4 o_position;
void main() 
{
    gl_Position = vec4(i_position, 0.0, 1.0);
};

Я написал это:

#version 330\n
layout(location=0) in vec2 i_position;
out vec4 o_position;
void main() 
{
    o_position = vec4(i_position, 0.0, 1.0);
};

Шейдеры компилируются без проблем в обоих случаях, но второй код выдает просто пустой экран. Нужно ли как-то указывать, какая переменная является выходной?


person michy04    schedule 25.06.2014    source источник
comment
Ни одна из этих встроенных переменных не считается устаревшей. До основных профилей (профилей совместимости) существовали встроенные функции, которые отражали фиксированные атрибуты конвейера, такие как gl_Color, gl_Normal и т. д.   -  person Brett Hale    schedule 25.06.2014
comment
О, тогда извини. Я читал, что некоторые переменные gl_* устарели, и думал, что все они устарели. Спасибо тебе за пояснение. В любом случае, как мне заставить его работать с пользовательской выходной переменной? Или вы просто используете атрибут gl_Position для установки позиции вершины?   -  person michy04    schedule 25.06.2014
comment
Вы все еще должны использовать gl_Position. Эта переменная особенная, потому что она определяет координаты, которые используются фиксированными функциональными блоками между вершинными и фрагментными шейдерами (отсечение, растеризация и т. д.). Вы не можете заменить его переменной, которую вы определяете. В дополнение к примерам, уже упомянутым @BrettHale, gl_FragColor, который раньше был предопределенным выходом шейдера фрагмента, также устарел.   -  person Reto Koradi    schedule 25.06.2014
comment
Понимаю. Я думал, что если вы можете указать пользовательские выходные данные в фрагментном шейдере, вы можете сделать это и в вершинном шейдере, видимо, я ошибался. Еще раз спасибо за разъяснение. Мне еще многому предстоит научиться, но пока что OpenGL доставляет мне огромное удовольствие.   -  person michy04    schedule 26.06.2014
comment
Вы можете сделать это, но gl_Position является частью gl_PerVertex. Точнее, это необязательная часть, все еще есть части с фиксированными функциями конвейера рендеринга, которые требуют gl_PerVertex.gl_Position. gl_FragCoord, как вы упомянули, фактически рассчитывается из этой переменной - после деления на w и преобразования области просмотра.   -  person Andon M. Coleman    schedule 26.06.2014


Ответы (2)


Это было в основном освещено в комментариях, но в интересах иметь ответ на месте, позвольте мне резюмировать, какие предопределенные переменные 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 был vec4, вывод фрагментного шейдера должен был быть вектором с плавающими компонентами. Это не работает, если ваша цель рендеринга имеет другой тип, например. если вы визуализируете целочисленную текстуру.

Итак, какие предопределенные переменные еще остались? Хотя их гораздо меньше, чем раньше, все же есть несколько, и все они относятся к фиксированным функциям, которые все еще присутствуют в программируемом конвейере. Примеры включают:

  • Интерфейс координат вершин между вершинным шейдером и фрагментным шейдером, который в основном состоит из выходных данных gl_Position в вершинном шейдере и входных данных gl_FragCoord во фрагментном шейдере. Между вершинными и фрагментными шейдерами все еще есть ряд фиксированных функциональных блоков, таких как отсечение и растеризация. Эти фиксированные функциональные блоки работают с координатами вершин, поэтому предопределенные переменные по-прежнему имеют смысл.
  • Некоторые переменные, связанные с созданием экземпляров (gl_VertexID, gl_InstanceID).
  • gl_ClipDistance для поддержки отсечения с произвольными плоскостями, которые также все еще присутствуют в форме фиксированной функции.
  • gl_FrontFacing. Порядок намотки треугольников оценивается фиксированной функцией и становится доступным для фрагментного шейдера.

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

person Reto Koradi    schedule 26.06.2014
comment
Спасибо всем за ответы, они действительно многое мне прояснили. OpenGL — довольно сложный API, поэтому многие вещи поначалу не очевидны. - person michy04; 26.06.2014

Как только что сказал наш коллега, gl_Position не устарела. Я только что купил книгу OpenGL Superbible 6th edition об OpenGL 4.3 и прямо на первых страницах (страница 18) используется эта функция.

Могу только порекомендовать приобрести книгу. Он написан людьми, разрабатывающими OpenGL, и это действительно поучительно.

Я тоже был потерян, как и вы раньше, потому что я пытался учиться через Интернет или обмен стеками, и после того, как я получил эту книгу, я прекрасно провожу время с OpenGL. Я думаю, что то, что я узнаю за три недели с книгой, будет более ценным, чем 5 лет обучения в Интернете. OpenGL не сложен и не является каким-то "зверем", как многие говорят, если вы изучаете его из этой книги. Если вы узнаете об этом через Интернет, я уверен, что это больше, чем зверь!

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

Вы можете купить эту книгу, бывшую в употреблении, на Amazon всего за 50 центов. Могу только рекомендовать!

person user5193682    schedule 11.11.2015
comment
Я думаю, что он сделал, если первое предложение. А затем подтвердил то, что я подозревал, Интернет не является полноценным ресурсом для понимания того, что происходит с шейдеризованными версиями OpenGL. Это позор, так как у OpenGL есть вики. - person Blair Houghton; 22.11.2015