【发布时间】:2013-12-02 11:04:43
【问题描述】:
我对如何创建着色器知之甚少,因此我对如何制作去饱和效果进行了一些研究,并为此借用了着色器代码。我现在遇到的一个问题是,当我尝试设置自定义颜色时,它似乎忽略了我给出的任何值。我想画一些完全黑色的东西,但 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 淡出某些东西时,它似乎也会去饱和。我有点理解,因为颜色的第三个变量是 a: alpha,这是我放置去饱和变量以发挥其效果的位置。也许有人可以帮助我了解这里发生了什么,也许我可以做些什么来重新获得修改颜色的能力以及保持对饱和度的动态控制。
【问题讨论】:
-
我与 HLSL 没什么关系,但是看着你的
main(...)着色器函数让我想到:不只使用color的a元素,即 Alpha?我没有看到你在任何地方使用r、g或b。 -
因为你正在你的纹理颜色和它的灰度之间进行线性插值(
lerp函数,不是吗?),当然它会变成灰色,而不是黑色或红色或任何你想。我不确定它是否会起作用,但请尝试将您的greyscale乘以color.rgb。如果color是白色的,即(1, 1, 1),那么什么都不会发生。如果是黑色,你的灰度应该变成(0, 0, 0),那么黑。如果是例如红色,你的灰度应该只在r元素中,所以:'(grayscale, 0, 0)`,从而给你“redscale”,而不是灰度。 -
显然,如果支持语句,那么可能是我添加
if(color.a != 999)之类的东西作为它调整颜色的条件的一种方式。一些条件语句让我从效果中排除某些东西,而不是让它与我设置的 RGB 值混淆。 -
我想最好的办法是把它画在一个没有应用效果的单独区域,我只是想把它画在那里是出于层/位置的原因。