Фрагментный шейдер и окраска текстуры
Я пытаюсь понять настройку цветов текстур с помощью фрагментарного шейдера. Мой фрагментарный шейдер супер прост:
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);