Действительно ли там что-то необычно о том, как альфа-компонент обрабатывается в пиксельном шейдере? У меня есть приложение WPF, для которого мой художник дает мне полутоновые изображения для использования в качестве фонов и приложения colorizes те изображения согласно текущему состоянию. Таким образом, я записал пиксельный шейдер (использующий инфраструктуру Библиотеки Эффектов Пиксельного шейдера WPF) для использования в качестве эффекта на Элемент изображения. Программа построения теней подражает в качестве параметра, который она преобразовывает в HSL, таким образом, она может управлять яркостью. Тогда для каждого серого пикселя, это вычисляет цвет, яркость которого интерполирована между цветным параметром и белая в пропорции к яркости исходного пикселя.
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 src = tex2D(implicitInputSampler, uv);
// ...Do messy computation involving src brightness and color parameter...
float4 dst;
dst.r = ...
dst.g = ...
dst.b = ...
dst.a = src.a;
return dst;
}
Это работает просто великолепно на пикселях где альфа = 1. Но где альфа = 0, результирующие пиксели выходят белые, вместо того, чтобы иметь фоновое шоу окна через. Таким образом, я внес крошечное изменение:
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 src = tex2D(implicitInputSampler, uv);
if (src.a == 0)
return src;
...
и теперь прозрачные части действительно прозрачны. Почему? Почему не сделал dst.a = src.a
оператор в первой версии выполняет это? К сожалению, даже это - только частичная фиксация, потому что она смотрит на меня как пиксели с 0 <альфа <1 выходит белая.
Кто-либо знает то, что я не понимаю об альфе?
После дополнительных поисков в Интернете я обнаружил часть, которой мне не хватало.
Согласно статье на MSDN: "WPF использует предварительно умноженную альфу везде внутри по ряду причин производительности, так что это также способ, которым мы интерпретируем значения цвета в пользовательском пиксельном шейдере."
Итак, исправление заключается в том, чтобы добавить умножение на альфа:
float4 main(float2 uv : TEXCOORD) : COLOR
{
...
dst.rgb *= src.a;
return dst;
}
И теперь мой вывод выглядит так, как я ожидаю.
0 <альфа <1 выходят белым
Какие диапазоны вы здесь ждете?
Все значения будут в диапазоне от 0,0 до 1,0 ... пиксельные шейдеры не работают в дискретных 256 цветовых диапазонах, они работают с плавающей запятой, где 1,0 - максимальная интенсивность.
Если в результате ваших вычислений значения r / g / b будут установлены на> 1.0, вы получите белый цвет ...
Чувак, я работаю над игрой XNA, и мне пришлось использовать пиксельный шейдер в градациях серого, и у меня возникла та же проблема, с которой столкнулись вы. Не знаю, знакомы ли вы со средой XNA или нет, но я решил проблему, изменив рисунок SpriteBatch SpriteBlendMode с SpriteBlendMode.None на SpriteBlendMode.AlphaBlend , надеюсь, это поможет вам, зная причина.
с уважением,