C# 去饱和效果不允许我设置自定义颜色

C# 去饱和效果不允许我设置自定义颜色,c#,xna,shader,effects,C#,Xna,Shader,Effects,我对如何创建着色器知之甚少,因此我对如何进行去饱和效果进行了一些研究,并借用了着色器代码。我现在遇到的一个问题是,当我尝试设置自定义颜色时,它似乎忽略了我给出的任何值。我想画一些完全黑色的东西,但是颜色。黑色以及新颜色(0,0,0,screen.SATURATION)不起作用。事实上,无论我输入什么RGB值,它看起来都是一样的 以下是着色器的代码: sampler TextureSampler : register(s0); float4 main(float4 color : COLOR0,

我对如何创建着色器知之甚少,因此我对如何进行去饱和效果进行了一些研究,并借用了着色器代码。我现在遇到的一个问题是,当我尝试设置自定义颜色时,它似乎忽略了我给出的任何值。我想画一些完全黑色的东西,但是
颜色。黑色
以及
新颜色(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
淡出时,它似乎也会降低饱和度。我理解这一点,因为颜色的第三个变量是a:alpha,这是我放置去饱和变量来实现其效果的地方。也许有人可以帮助我了解这里发生了什么,也许我可以做些什么来重新获得修改颜色的能力,并保持对饱和度的动态控制。

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

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
float4 color
参数将获得通过
SpriteBatch.Draw()
传入的值,因为它被标记为
COLOR0

bog标准像素着色器除了输出着色纹理颜色外不执行任何操作,如下所示:

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
    return tex2D(TextureSampler, texCoord) * 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通道进行着色。

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

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
float4 color
参数将获得通过
SpriteBatch.Draw()
传入的值,因为它被标记为
COLOR0

bog标准像素着色器除了输出着色纹理颜色外不执行任何操作,如下所示:

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
    return tex2D(TextureSampler, texCoord) * 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通道进行着色。

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

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
float4 color
参数将获得通过
SpriteBatch.Draw()
传入的值,因为它被标记为
COLOR0

bog标准像素着色器除了输出着色纹理颜色外不执行任何操作,如下所示:

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
    return tex2D(TextureSampler, texCoord) * 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通道进行着色。

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

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
float4 color
参数将获得通过
SpriteBatch.Draw()
传入的值,因为它被标记为
COLOR0

bog标准像素着色器除了输出着色纹理颜色外不执行任何操作,如下所示:

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
    return tex2D(TextureSampler, texCoord) * 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通道进行着色。

我对HLSL没有太多关系,但看着你的
主(…)
着色器函数,我会想:你不是只使用
颜色
元素,即Alpha吗?我没有看到你在任何地方使用
r
g
b
。因为你在纹理颜色和灰度之间进行线性插值(
lerp
函数,不是吗?),当然它会变成灰色,而不是黑色或红色或任何你想要的颜色。我不确定它是否有效,但请尝试将您的
greyscale
乘以
color.rgb
。如果
颜色
为白色,即
(1,1,1)
,则不应发生任何事情。如果它是黑色的,你的灰度应该变成
(0,0,0)
,所以是黑色的。如果它是例如红色,那么你的灰度应该只在
r
元素中,所以:“(灰度,0,0)`,因此给你“红标”,而不是灰度。显然,如果支持语句,那么这可能是我添加类似
If(color.a!=999)
的内容,作为它对颜色进行lerp的条件。对于我来说,一些条件声明可以将某些东西从效果中排除,并且不会使它与我正在绘制的东西设置的RGB值相混淆。我认为最好的方法是在一个单独的区域中绘制它,该效果不适用于该区域,我只是出于图层/位置的原因在那里绘制它。我与HLSL没有太多关系,但是看着你的
main(…)
shader函数,我想:你不仅仅使用
color
元素