在WPF像素着色器效果中处理Alpha通道

时间:2010-02-05 03:57:49

标签: wpf pixel alphablending pixel-shader

在像素着色器中如何处理alpha分量有什么不寻常之处吗?我有一个WPF应用程序,我的艺术家为我提供灰度图像作为背景,应用程序根据当前状态着色这些图像。所以我写了一个像素着色器(使用WPF像素着色器效果库基础结构)来用作Image元素的效果。着色器将颜色作为参数,将其转换为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;
}

这对于alpha = 1的像素效果很好。但是在alpha = 0的情况下,结果像素变为白色,而不是让窗口的背景显示出来。所以我做了一个微小的改变:

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 src = tex2D(implicitInputSampler, uv);
    if (src.a == 0) 
        return src;
    ...

现在透明部分确实是透明的。为什么?为什么第一个版本中的dst.a = src.a语句没有实现呢?不幸的是,即使这只是一个部分修复,因为它看起来像0< alpha< 1出现白色。

有谁知道我不了解alpha?

3 个答案:

答案 0 :(得分:21)

经过一些网络搜索后,我发现了我失踪的那篇文章。

根据an article on MSDN:“由于许多性能原因,WPF在内部到处使用预乘的alpha,因此这也是我们解释自定义像素着色器中颜色值的方式。”

所以修复结果是抛出乘以alpha:

float4 main(float2 uv : TEXCOORD) : COLOR
{
    ...
    dst.rgb *= src.a;
    return dst;
}

现在我的输出看起来像我期望的那样。

答案 1 :(得分:-1)

  

0< alpha< 1出现白色

您对此有何期待?

所有值都将在0.0和1.0范围内...像素着色器在离散的256色范围内不起作用,它们是浮点,其中1.0是最大强度。

如果你的计算最终将r / g / b值设置为> 1.0,那么你将会变白......

http://www.facewound.com/tutorials/shader1/

答案 2 :(得分:-1)

Dude我正在开发XNA游戏,我不得不使用灰度像素着色器,我遇到了你面临的同样问题。 如果您熟悉XNA环境我不知道,但是我通过更改 SpriteBatch 绘图 SpriteBlendMode SpriteBlendMode.None SpriteBlendMode.AlphaBlend ,我希望这可以帮助您了解原因。

的问候,