Соответствие между текстурными единицами и сэмплерными формами в opengl - PullRequest
0 голосов
/ 28 февраля 2019

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

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

Так, например, если вершинный шейдер определяет:

uniform sampler2D color;

И фрагментный шейдер определяет:

uniform sampler2D tex;
uniform sampler2D norm;

Затем color сопоставляется с gl_TEXTURE0, tex сопоставляется с gl_TEXTURE1, а norm сопоставляется с gl_TEXTURE2.Но если вместо этого вершинный шейдер определяет:

uniform sampler2D norm;

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

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

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Вот что мне удалось найти:

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

Ничего из этого не соответствует действительности.Хорошо, первое верно, но только случайно.

Все унифицированные значения, которые не инициализируются в шейдере, инициализируются значением 0. Спецификация делает это совершенно ясным:

Любой унифицированный сэмплер или переменная изображения, объявленные без квалификатора привязки, изначально привязаны к единице 0.

Значение униформы сэмплера - это целочисленный индекс единицы текстуры, которую он представляет.Таким образом, значение 0 соответствует GL_TEXTURE0.Все неинициализированные формы сэмплера должны иметь значение 0.

Если описанное вами поведение происходит, то эта реализация нарушает 1028 * спецификации OpenGL.

Если только выиспользуйте синтаксис layout(binding = ), чтобы назначить единицу текстуры униформы, вы должны вручную в своем коде OpenGL назначить каждой форме сэмплера значение для его единицы текстуры.Это делается путем установки его универсального значения, как и любой другой целочисленной униформы: вы вызываете glUniform1i с местоположением, соответствующим этой униформе.Поэтому, если вы хотите связать его с индексом блока изображения текстуры 4, вы вызываете glUniform1i(..., 4), где ... - это унифицированное местоположение для этой униформы.

0 голосов
/ 28 февраля 2019

Вы должны установить индекс единицы текстуры на единицу выборки (аналогично установке значения универсальной переменной типа int).например, значение 1 для GL_TEXTURE1.

См. Спецификация профиля совместимости API OpenGL 4.6;7.10 Пробоотборники;стр. 154 :

Сэмплеры - это специальные формы, используемые в языке затенения OpenGL для идентификации объекта текстуры, используемого для каждого поиска текстуры.Значение сэмплера указывает на доступ к единице изображения текстуры.При установке значения сэмплера на i выбирается номер единицы изображения текстуры i.

например,

layout (location = 11) uniform sampler2D color;
layout (location = 12) uniform sampler2D tex;
layout (location = 13) uniform sampler2D norm;
glUniform1i(11, 0); // 0: GL_TEXTURE0
glUniform1i(12, 1); // 1: GL_TEXTURE1
glUniform1i(13, 2); // 2: GL_TEXTURE2

Начиная с версии 4.2 GLSL это можно сделать в фрагментном шейдере, указав точки привязки - см. Язык затенения OpenGL 4.20 Спецификация - 4.4.4 Классификаторы непрозрачной формы;страница 60 :

#version 420

layout (binding = 0) uniform sampler2D color;
layout (binding = 1) uniform sampler2D tex;
layout (binding = 2) uniform sampler2D norm;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...