使用Tint Sprite White处的简单着色器和Sprite Effects Sample处的示例代码,我已将着色器的.fx文件加载到示例项目中,并将其中一个示例效果替换为其中一个Draw()调用使用美白效果。
我得到的是一个大的白色方块,其尺寸与纹理本身相同。我显然只想要将alpha不为0的纹理区域变为白色。着色器似乎正在工作,因为我将默认的白色更改为其他测试用例,并且方块确实会改变颜色。
我在自己的一个简单项目中尝试了这个并得到了相同的结果。如何确保只有纹理的可见部分被着色?
修改后的调用如下所示:
spriteBatch.Begin(0, null, null, null, null, whiteEffect);
spriteBatch.Draw(myTexture, CenterOnScreen(myTexture), Color.White);
spriteBatch.End();
答案 0 :(得分:5)
首先,仔细检查以确保您的图片中有alpha。
该着色器假设您使用的是非预乘alpha:
batch.Begin(0, BlendState.NonPremultiplied, null, null, null, whiteEffect);
着色器使用纹理的alpha值作为美白的基础;换句话说,α越坚固,美白效果越坚固。如果你不想要任何“中间”(例如部分白色),如果你的纹理中没有“中间”alpha,它就会起作用。
float4 ps_main( PS_INPUT Input ) : COLOR0
{
float4 color = tex2D( baseMap, Input.Texcoord );
return float4(1.0f, 1.0f, 1.0f, color.a);
}
编辑:由于询问了预乘版本,我将添加该版本并附上解释。
将非预乘颜色转换为预乘格式:
color.rgb * = color.a
让我们在着色器中执行相同的操作:
float4 ps_main( PS_INPUT Input ) : COLOR0
{
float4 color = tex2D( baseMap, Input.Texcoord );
return float4(color.a, color.a, color.a, color.a);
}
现在您可以继续使用默认的alpha混合状态:
batch.Begin(0, BlendState.AlphaBlend, null, null, null, whiteEffect);
我仍然不确定你是否想要坚硬的“白色或透明”......在这种情况下,如果你预先成倍增加并不重要,因为你可以做一个“布尔”风格返回纯白色(1.0f,1.0f,1.0f,1.0f)或纯透明(0.0f,0.0f,0.0f,0.0f);无论混合状态如何,这些特定颜色都会显示相同的颜色:
float4 ps_main( PS_INPUT Input ) : COLOR0
{
float4 color = tex2D( baseMap, Input.Texcoord );
if (color.a > 0.0f)
{
return float4(1.0f, 1.0f, 1.0f, 1.0f);
}
else
{
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
}