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

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

uniform sampler2D sampler;

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

Это рисует мою текстуру собаки, как и ожидалось: normal dog

если затем изменить шейдер на

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

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

no transparency

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

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

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

green dog

Что происходит?

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

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

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

red dog

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

Ответы

Ответ 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);