Фрагмент шейдера GLSL для текстуры, цвета и текстуры / цвета - PullRequest
4 голосов
/ 14 июля 2011

Я хочу создать шейдер GLSL, который может текстурировать и окрашивать мои объекты вершин.На самом деле, это работает для меня в 2 из 3 случаев:

1) Если у меня есть только назначенная текстура (но не определенный цвет - поэтому цвет "белый"), я просто получаю текстурированный объект -работает

2) Если у меня есть текстура и назначенный цвет, я получаю текстурированный объект, модулированный этим цветом - работает

3) Если у меня есть только назначенный цвет, но нет текстуры, яполучить черный объект - не работает

Мой шейдер выглядит так:

varying lowp vec4 colorVarying;
varying mediump vec2 texcoordVarying;
uniform sampler2D texture;

void main(){
    gl_FragColor = texture2D(texture, texcoordVarying) * colorVarying;
}

Я полагаю, что texture2D (..., ...) возвращает ноль, если текстуры нетназначен - так что, кажется, проблема.Есть ли способ в GLSL, я могу проверить, если текстура не назначена (в этом случае, я просто хочу gl_FragColor = colorVarying;)

«Если» на самом деле не вариант в шейдере GLSL, если яправильно понял - есть идеи для этого?Или действительно нужно сделать 2 разных шейдера для обоих случаев?

1 Ответ

5 голосов
/ 14 июля 2011

Как и вы, я подобрал общий совет, которого следует избегать «если» на текущем мобильном оборудовании, но предыдущее обсуждение оптимизации StackOverflow показало, что это не является существенным препятствием. Так что не списывай со счетов. В любом случае, GLSL-компилятор достаточно умен и может выбрать, какой код он на самом деле выполняет, в зависимости от значений, заданных для униформ, хотя в этом случае все, что вы получаете, такое же, как если бы вы просто предоставили альтернативные шейдеры.

Тем не менее, если вы абсолютно уверены, что хотите использовать один и тот же шейдер для всех целей и хотите избежать операторов if, тогда вам, вероятно, нужно что-то вроде:

uniform lowp float textureFlag;

[...]

gl_FragColor = textureFlag * texture2D(texture, texcoordVarying) * colorVarying + 
               (1.0 - textureFlag) * colorVarying;

Или даже:

gl_FragColor = mix(
                     colorVarying,
                     texture2D(texture, texcoordVarying) * colorVarying,
                     textureFlag
                  )

Когда вы устанавливаете textureFlag на 1,0 или 0,0, в зависимости от того, хотите ли вы, чтобы значения текстуры были учтены.

Мне неизвестен какой-либо способ определить (i) указывает ли Sampler2D на фактическую текстурную единицу; и (ii) имеет ли конкретный текстурный блок связанный с ним буфер, для которого были загружены данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...