Незакрепленная текстура OpenGL ссылается на другую текстуру

#opengl #textures

#opengl #Текстуры

Вопрос:

Если у меня есть шейдер, который использует две текстуры, и одна из них не настроена для первых нескольких отрисовок (потому что я выбираю ее по сети), программа будет использовать вторую текстуру для первой, вместо выборки из черного цвета по умолчанию.

Например, если мой фрагментный шейдер:

 uniform sampler2D texture1;
uniform sampler2D texture2; // this is a color filter

varying mediump vec2 v_textureCoordinate;

void main() {
  mediump vec3 rgb = texture2D(texture1, v_textureCoordinate);
  rgb.r = texture2D(texture2, vec2(rgb.r, 0.5).r);

  gl_FragColor = vec4(rgb, 1.0);
}
  

и я использую ее после texture2 установки и до texture1 установки, выборка из texture1 будет выбираться из texture2 , а не из пустой текстуры по умолчанию. Почему это так?

Ответ №1:

вместо выборки из черного цвета по умолчанию

Не существует такой вещи, как «черная текстура по умолчанию». sampler Типы ссылаются не на текстуры в GLSL, а на единицы текстуры. Таким образом, либо есть какая-то полная текстура, привязанная к (соответствующей цели) этой текстурной единице, либо ее нет.

Как указал Андон М. Коулман в комментариях, концептуально нет способа не привязывать текстуру, поскольку объект текстуры 0 ссылается на действительный объект текстуры в GL, объект текстуры по умолчанию. Но изначально она не содержит никаких данных изображения, поэтому она просто неполная.

Обновить

При выборке из неполной текстуры возвращаемое значение вашей операции выборки будет просто неопределенным.

На самом деле, как отметил Рето Коради в комментарии, выборка из неполной текстуры четко определена в GL. Это даст результат (0,0,0,1). Однако при использовании texelFetch с неполной текстурой результаты будут неопределенными (если только контекст не был создан с надежным поведением доступа к буферу).

Но поскольку вы используете texture2D , здесь вы будете в безопасности. Однако вы не получаете доступ к неполной текстуре. Униформы по умолчанию инициализируются нулем. В результате оба texture1 и texture2 изначально будут ссылаться на текстурную единицу GL_TEXTURE0 . Если вы используете этот модуль для своего первого использования texture2 , то texture1 сэмплер в конечном итоге получит доступ к той же текстуре.

Комментарии:

1. Понятно, спасибо. Есть идеи о том, как создать черную текстуру во время загрузки реального содержимого? Я действительно не мог что-то найти.

2. Создание фиктивного текста размером 1×1 с одним черным пикселем не должно быть очень сложным.

3. Всегда есть что-то, привязанное к текстурной единице: P Даже имя 0 является допустимой текстурой с изначально неполным состоянием ( 0 уникально для каждой цели, но это в стороне функционирует как обычная текстура). Состояние этой текстуры со временем будет повреждаться во многих приложениях, потому что многие разработчики предполагают, что привязка 0 означает, что команды текстуры не имеют эффекта :-

4. Многое из этого неверно. Выборка из неполной текстуры гарантированно даст черный цвет. См., например, Раздел 3.9.2 спецификации OpenGL 3.3.

5. @RetoKoradi: вы совершенно правы. Я посмотрел в спецификации, прежде чем написать ответ. Однако я оказался не в том месте (в разделе спецификации GL3.3 2.11.7), который охватывает выборки texel, а не выборки текстур… Я обновлю свой ответ.