Шейдер фрагментов и раскрашивание текстуры
Я пытаюсь найти смысл в настройке цветов текстуры с помощью шейдера фрагментов. Мой шейдер фрагментов очень прост:
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 ответ:
Ваш режим смешивания предполагал предварительно умноженную Альфа-волну, что обычно является отличным выбором. Но для этого требуется, чтобы значения 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);