去饱和效果不让我设置自定义颜色

时间:2013-12-02 11:04:44

标签: c# xna shader effects

我对如何创建着色器知之甚少,因此我对如何进行去饱和效果进行了一些研究并借用了着色器代码。我现在遇到的一个问题是,当我尝试设置自定义颜色时,似乎忽略了我给出的任何值。我想绘制完全黑色的东西但Color.Black以及new Color(0, 0, 0, screen.SATURATION)不起作用。事实上,无论我输入什么RGB值,它看起来都是一样的。

以下是着色器的代码:

sampler TextureSampler : register(s0);

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
    // Look up the texture color.
    float4 tex = tex2D(TextureSampler, texCoord);

    // Convert it to greyscale. The constants 0.3, 0.59, and 0.11 are because
    // the human eye is more sensitive to green light, and less to blue.
    float greyscale = dot(tex.rgb, float3(0.3, 0.59, 0.11));

    // The input color alpha controls saturation level.
    tex.rgb = lerp(greyscale, tex.rgb, color.a * 4);

    return tex;
}


technique Desaturate
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 main();
    }
}

我的开始就是这样:

ScreenManager.SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, desaturateEffect, Resolution.getTransformationMatrix() * cam.get_transformation(graphics.GraphicsDevice));

着色器的另一个副作用是,当我通过color * float淡出时,它似乎也会对它进行去饱和处理。那个我有点理解,因为颜色的第三个变量是:alpha,这是我放置去饱和变量来实现其效果的地方。也许有人可以帮助我理解这里发生了什么,也许我可以做些什么来重新获得修改颜色的能力以及保持动态控制饱和度。

1 个答案:

答案 0 :(得分:3)

SpriteBatch.Draw()中指定颜色值时,它会以COLOR0语义传递到输入参数中。也就是说,在这里:

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0

float4 color参数将被赋予您通过SpriteBatch.Draw()传递的值,因为它被标记为COLOR0

沼泽标准像素着色器除了输出有色纹理颜色外什么都不做,如下所示:

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
    return tex2D(TextureSampler, texCoord) * color;
}

注意乘以color。这将纹理的R乘以颜色的R,纹理的G乘以颜色的G,依此类推,通过B和A,着色纹理提供的原始颜色。

所以你可能想要做的是:

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
    // Look up the texture color.
    float4 tex = tex2D(TextureSampler, texCoord);
    tex.rgb *= color.rgb;

    // Convert it to greyscale. The constants 0.3, 0.59, and 0.11 are because
    // the human eye is more sensitive to green light, and less to blue.
    float greyscale = dot(tex.rgb, float3(0.3, 0.59, 0.11));

    // The input color alpha controls saturation level.
    tex.rgb = lerp(greyscale, tex.rgb, color.a * 4);

    return tex;
}

在计算灰度值或执行lerp之前,这将使原始纹理颜色 - 但仅限RGB通道 - 着色。