10

在像素着色器中如何处理 alpha 分量有什么不寻常的地方吗?我有一个 WPF 应用程序,我的艺术家给我灰度图像用作背景,应用程序根据当前状态为这些图像着色。因此,我编写了一个像素着色器(使用 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;
}

这在 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 不了解的地方?

4

3 回答 3

24

经过更多的网络搜索后,我发现了我丢失的部分。

根据MSDN 上的一篇文章:“出于多种性能原因,WPF 在内部各处都使用预乘 alpha,因此这也是我们在自定义像素着色器中解释颜色值的方式。”

所以解决方法是用 alpha 乘法:

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

现在我的输出看起来和我期望的一样。

于 2010-02-10T22:41:48.127 回答
-1

0 < alpha < 1 是白色的

你在这里期待什么范围?

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

如果您的计算最终将 r/g/b 值设置为 >1.0,您将获得白色...

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

于 2010-02-05T08:34:14.030 回答
-1

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

问候,

于 2010-02-09T17:07:50.913 回答