Шейдер фрагментов и раскрашивание текстуры


Я пытаюсь найти смысл в настройке цветов текстуры с помощью шейдера фрагментов. Мой шейдер фрагментов очень прост:

uniform sampler2D sampler;

void main() {
  vec4 tex = texture2D ( sampler, uvVarying );
  gl_FragColor = vec4(tex.r, tex.g, tex.b, tex.a);
}

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

Если я затем изменю шейдер на

  gl_FragColor = vec4(tex.r, tex.g, tex.b, 1.0);

Результат таков, как я и ожидал, информация о прозрачности потеряна:

никакой прозрачности

Но если я вместо этого установлю его в:

  gl_FragColor = vec4(tex.r, tex.g, tex.b, 0.0);

Я ожидал, что он исчезнет полностью, но вместо этого я получаю:

зеленая собака

Что происходит дальше??

И к моей первоначальной проблеме: я хотел добавить немного красного оттенка к моей текстуре с помощью:

  gl_FragColor = vec4(tex.r + 0.5, tex.g, tex.b, tex.a);

Теперь я ожидал, что он будет иметь ту же информацию о прозрачности, что и исходная текстура, но вместо этого я получаю следующее:

рыжая собака

Чего мне здесь не хватает. Текстура использует смешивание по умолчанию движка, который является src = GL_ONE, dst = GL_ONE_MINUS_SRC_ALPHA.

1 16

1 ответ:

Ваш режим смешивания предполагал предварительно умноженную Альфа-волну, что обычно является отличным выбором. Но для этого требуется, чтобы значения RGB были умножены на значение альфа. Альфа-значение только определяет, сколько фона добавляется к входящим фрагментам в этом режиме. Поэтому, чтобы заставить RGB "исчезать", они также должны быть модулированы значением Альфа.

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

gl_FragColor = tex + vec4(0.5, 0, 0, 1)*tex.a;
Это добавляет к текстуре Альфа-модулированный красный цвет.

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

gl_FragColor = vec4(tex.rgb/tex.a, tex.a);