2016-06-08 5 views
0

Я редактирую шейдер, который был написан для текстур RGBA.Смешивание изображений формата RGBA и ALPHA в шейдерах GLSL

Это работает, как ожидалось с RGBA текстур, например:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

... затем в GLSL шейдер, его значение можно получить с. texture2D(tex, coord);

Это все работает нормально.

Однако, одна часть программного обеспечения использует альфа-только текстуры
(где его format аргумент является GL_ALPHA), например:

glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, x, y, 0, , GL_ALPHA, GL_UNSIGNED_BYTE, NULL);

В этом случае компоненты RGB от texture2D() все равны нулю.


Хотя это ожидаемое поведение, я хотел бы знать, если есть способ либо:

  • установить RGB значения для альфа-текстур, только возвращенных texture2D
    (который Безразлично 't разорвать текстуры RGBA).
  • Проверьте шейдер для такого типа текстуры, чтобы обрабатывать его по-разному.

Обратите внимание, что это может быть обработано с препроцессором определяет в качестве последнего средства, но это уже полный #if-х, так что я бы избежать, если это возможно, так как число комбинаций до процессора увеличивается число шейдеров, которые нам нужно хранить.

+0

«Тем не менее, одна часть программного обеспечения использует текстуру только альфа (где ее аргумент arg - GL_ALPHA), например: *« FYI: это не «только альфа-текстура». Формат [формат передачи пикселей] (https://www.opengl.org/wiki/Pixel_Transfer#Pixel_format) описывает данные, которые вы загружаете.Формат данных в текстуре - это [внутренний формат] (https://www.opengl.org/wiki/Image_Format), который вы не показывали. Таким образом, для всего, что мы знаем, ваша текстура только для альфа-канала может быть текстурой RGBA. –

+0

@ nicol-bolas, хотел избежать * шума *, но ваше право, обновил вопрос. – ideasman42

+0

Связанный вопрос: https://www.opengl.org/discussion_boards/showthread.php/175008-using-alpha-blending-with-shaders – ideasman42

ответ

4

Вы можете использовать texture swizzling, чтобы установить значение, извлеченное из любого компонента текстуры. Поэтому, если у вас действительно есть текстура с альфа-версией, вы можете использовать маску swizzle для установки значений RGB в 1. Или для трансляции альфа-значения в других трех. Или вы можете установить их в 0, но это значение по умолчанию, если они не в текстуре.

//Set other components to 1. 
GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; 
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); 

Очевидно, что текстура должна быть связана с этим.

Но это ваши единственные варианты. Вы не можете установить недостающие компоненты в произвольные значения.

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

vec4 val = texture(tex_unit, ...); 
val.xyz = fill_defaults ? defaults : val.xyz; 

Простой ?: на динамически однородного значения не будет иметь никакого реального влияния на производительность.

+0

Текстура swizzle отлично работает, спасибо! – ideasman42

Смежные вопросы