代码之家  ›  专栏  ›  技术社区  ›  Connor John Macaskill

如何更改特定精灵纹理的颜色?

  •  0
  • Connor John Macaskill  · 技术社区  · 14 年前

    现在我在精灵类中使用一个名为SetTextureColour的函数:

        public void SetTextureColour(Color Colour)
        {
            Color[] data = new Color[Texture.Width * Texture.Height];
            Texture.GetData(data);
    
            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] == Color.White)
                {
                    data[i] = Colour;
                }
            }
            Texture.SetData(data);
        }
    

    要将精灵纹理中每个白色像素的颜色更改为指定的颜色,这很好,但我遇到的问题是,它会更改共享该纹理的每个精灵的颜色,而不仅仅是单个精灵的颜色。有没有人有一个解决方案,这样我就可以只更改该精灵纹理的像素,这样我可以使用为具有相同纹理的多个精灵指定不同颜色的函数。

    提前谢谢。

    编辑:

    根据建议,我尝试使用像素着色器来完成这项工作,尽管我以前从未使用过它们,但到目前为止,我已经按照建议完成了-

    sampler TextureSampler : register(s0);
    float3 key_color;
    float3 new_color;
    
    float4 ChangePixel(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
    {
      float4 newColor = tex2D(TextureSampler, texCoord);
    
      if (distance(key_color, color.rgb)<0.001f)
      {
         color.rgb = new_color;
      } 
    
      return newColor;
    } 
    
    technique PixelChange
    {
        pass Pass0
        {
            PixelShader = compile ps_2_0 ChangePixel();
        }
    }
    

    它是用加载内容加载的,我也用这个设置了它的技术-

            Effect1.CurrentTechnique = Effect1.Techniques["PixelChange"];
    

    然后我用这两行设置值-

            Effect1.Parameters["key_color"].SetValue(Color.White.ToVector3());
            Effect1.Parameters["new_color"].SetValue(Color.Red.ToVector3());
    

    但它似乎什么都没做,有人能帮我解决这个问题吗?正如我所说,这是第一次使用着色器,所以我可以使用一些帮助。

    最后一点,这个效果是在spriteBatch.Begin中使用的,所以这不是没有应用效果的问题。

    2 回复  |  直到 14 年前
        1
  •  2
  •   Blau    14 年前

    你可以使用一个着色器为你做到这一点。。。

    sampler texture : register(s0);
    float3 key_color = float3(1,1,1);
    float3 new_color;
    
    float4 pixel_shader_that_replaces_color(in float4 color:COLOR0, in float2 coords:TEXCOORDS) : COLOR0
    {
          float4 color = tex2D(texture, coords);
          if (distance(key_color, color.rgb)<0.001f)
          {
             color.rgb = new_color;
          } 
          return color;
    } 
    

    在你的代码中,你必须加载新的效果。。。对于你想画的每一种颜色,都要这样做。。。

     effect.SetValue("key_color", Color.White.ToVector3());
     effect.SetValue("new_color", yourcolor.ToVector3());
     spritebatch.Begin(-...., , ,, effect);
         // Inside this all your texture pixels with Color.White will be replaced to newColor
     spritebatch.End()
    

    你必须调用sprite。从你想要的每个新颜色开始。。但我认为这比设置纹理数据要好。。。

    PD:我正在写代码。。。它需要一些额外的工作。。。就像你能找到的顶点着色器 inside the stock sample ,但这些是最基本的:)

        2
  •  0
  •   Connor John Macaskill    14 年前

    多亏了回答我问题的人和facepunch上的人的帮助,我找到了解决方案-

    sampler TextureSampler : register(s0);
    float3 key_color;
    float3 new_color;
    
    float4 ChangePixel(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
      {
        float4 newColor = tex2D(TextureSampler, texCoord);
    
      if (distance(key_color, newColor.rgb)<0.001f)
      {
         newColor.rgb = new_color;
      } 
    
      return newColor * color;
    } 
    
    technique PixelChange
    {
        pass Pass0
        {
           PixelShader = compile ps_2_0 ChangePixel();
       }
    }
    

    若要使用着色器,请使用-

            Effect1.Parameters["key_color"].SetValue(Color.White.ToVector3());
            Effect1.Parameters["new_color"].SetValue(Color.Aqua.ToVector3());
    

    关键颜色设置了要搜索的颜色,新颜色是替换它的颜色,感谢大家的帮助!