在XNA 4.0中使用简单着色器(alpha问题)制作精灵白色

时间:2012-03-07 09:32:11

标签: c# xna sprite shader xna-4.0

使用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();

1 个答案:

答案 0 :(得分:5)

首先,仔细检查以确保您的图片中有alpha。

该着色器假设您使用的是非预乘alpha:

batch.Begin(0, BlendState.NonPremultiplied, null, null, null, whiteEffect);

着色器使用纹理的alpha值作为美白的基础;换句话说,α越坚固,美白效果越坚固。如果你不想要任何“中间”(例如部分白色),如果你的纹理中没有“中间”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);
   }

编辑:由于询问了预乘版本,我将添加该版本并附上解释。

来自this helpful article

  

将非预乘颜色转换为预乘格式:

     

color.rgb * = color.a

让我们在着色器中执行相同的操作:

预乘的部分白色Alpha版本

   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);
   }
}