Colors C#/XNA/HLSL-在2D精灵上应用像素着色器会影响同一渲染目标上的其他精灵

Colors C#/XNA/HLSL-在2D精灵上应用像素着色器会影响同一渲染目标上的其他精灵,colors,xna,2d,xna-4.0,hlsl,Colors,Xna,2d,Xna 4.0,Hlsl,背景信息 我刚刚开始学习HLSL,并决定通过编写一个简单的2D XNA 4.0子弹地狱游戏来测试我从互联网上学到的东西 我已经写了一个像素着色器,以改变子弹的颜色 想法如下:子弹的原始纹理主要是黑色、白色和红色。在我的像素着色器的帮助下,子弹可以更加多彩 但是,我不确定着色器是如何以及何时应用于XNA4.0中的spriteBatch的,以及何时结束。这可能是问题的原因。 XNA3.x中有pass.begin()和pass.end(),但XNA4.0中的pass.apply()使我感到困惑 此外

背景信息

我刚刚开始学习HLSL,并决定通过编写一个简单的2D XNA 4.0子弹地狱游戏来测试我从互联网上学到的东西

我已经写了一个像素着色器,以改变子弹的颜色

想法如下:子弹的原始纹理主要是黑色、白色和红色。在我的像素着色器的帮助下,子弹可以更加多彩

但是,我不确定着色器是如何以及何时应用于XNA4.0中的spriteBatch的,以及何时结束。这可能是问题的原因。 XNA3.x中有pass.begin()和pass.end(),但XNA4.0中的pass.apply()使我感到困惑

此外,这是我第一次使用renderTarget。这可能会引起问题

症状

它可以工作,但前提是项目符号列表中有相同颜色的项目符号。 如果渲染不同颜色的项目符号,则会生成错误的颜色

像素着色器似乎未应用于项目符号纹理,而是应用于包含所有渲染项目符号的renderTarget

例如: 这里有一些红色子弹和蓝色子弹。最后创建的项目符号是蓝色的。似乎像素着色器在红色的像素上添加了蓝色,使其成为蓝紫色

如果我继续创建项目符号,红色项目符号将在红色和蓝紫色之间切换。(我相信蓝色的也在转换,但并不明显。)

代码

由于我是HLSL的新手,我真的不知道我必须提供什么。 以下是所有我相信或不知道的事情,它们是否与问题有关

C#-敌人的子弹(或仅仅是子弹):

受保护的SpriteBatch SpriteBatch;
保护纹理2D纹理;
保护效应;色彩效应;
保护色;
... // 还有一些不相关的变量
public EnemyBullet(SpriteBatch SpriteBatch、Texture2D纹理、Effect colorEffect、BulletType BulletType)(以及其他数据,如速度)
{
this.spriteBatch=spriteBatch;
这个纹理=纹理;
this.colorEffect=colorEffect;
if(bulletType==bulletType.ARROW\S)
{
bulletColor=Color.Red;//项目符号将为红色
}
其他的
{
bulletColor=Color.Blue;//或蓝色。
}
}
公共无效更新()
{
…//更新位置和其他属性,但不更新颜色。
}
公众抽签()
{
colorEffect.Parameters[“DestColor”].SetValue(bulletColor.ToVector4());
int l=colorEffect.currentTechnical.passs.Count();
对于(int i=0;i
C#-项目符号管理器:

private Texture2D bulletTexture;

private List<EnemyBullet> enemyBullets;
private const int ENEMY_BULLET_CAPACITY = 10000;

private RenderTarget2D bulletsRenderTarget;

private Effect colorEffect;

...

public EnemyBulletManager()
{
    enemyBullets = new List<EnemyBullet>(ENEMY_BULLET_CAPACITY);
}

public void LoadContent(ContentManager content, SpriteBatch spriteBatch)
{
    bulletTexture = content.Load<Texture2D>(@"Textures\arrow_red2");

    bulletsRenderTarget = new RenderTarget2D(spriteBatch.GraphicsDevice, spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth, spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Color, DepthFormat.None);

    colorEffect = content.Load<Effect>(@"Effects\ColorTransform");
    colorEffect.Parameters["ColorMap"].SetValue(bulletTexture);
}

public void Update()
{
    int l = enemyBullets.Count();
    for (int i = 0; i < l; i++)
    {
        if (enemyBullets[i].IsAlive)
        {
            enemyBullets[i].Update();
        }
        else
        {
            enemyBullets.RemoveAt(i);
            i--;
            l--;
        }
    }
}

// This function is called before Draw()
public void PreDraw()
{
    // spriteBatch.Begin() is called outside this class, for reference:
    // spriteBatch.Begin(SpriteSortMode.Immediate, null);

    spriteBatch.GraphicsDevice.SetRenderTarget(bulletsRenderTarget);
    spriteBatch.GraphicsDevice.Clear(Color.Transparent);

    int l = enemyBullets.Count();
    for (int i = 0; i < l; i++)
    {
        if (enemyBullets[i].IsAlive)
        {
            enemyBullets[i].Draw();
        }
    }

    spriteBatch.GraphicsDevice.SetRenderTarget(null);
}

public void Draw()
{
    // Before this function is called,
    // GraphicsDevice.Clear(Color.Black);
    // is called outside.

    spriteBatch.Draw(bulletsRenderTarget, Vector2.Zero, Color.White);

    // spriteBatch.End();
}

// This function will be responsible for creating new bullets.
public EnemyBullet CreateBullet(EnemyBullet.BulletType bulletType, ...)
{
    EnemyBullet eb = new EnemyBullet(spriteBatch, bulletTexture, colorEffect, bulletType, ...);
    enemyBullets.Add(eb);
    return eb;
}
私有纹理2D bulletTexture;
私人名单;
敌方私人警察的子弹容量=10000;
私有渲染目标2D bulletsRenderTarget;
私人效应;
...
公共EnemyBulletManager()
{
enemyBullets=新列表(敌人的子弹容量);
}
公共void加载内容(ContentManager内容,SpriteBatch SpriteBatch)
{
bulletTexture=content.Load(@“Textures\arrow_red2”);
BulletsUnderTarget=new RenderTarget2D(spriteBatch.GraphicsDevice、spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth、spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight、false、SurfaceFormat.Color、DepthFormat.None);
colorEffect=content.Load(@“Effects\ColorTransform”);
colorEffect.Parameters[“ColorMap”].SetValue(bulletTexture);
}
公共无效更新()
{
int l=enemyBullets.Count();
对于(int i=0;i
HLSL-Effects\ColorTransform.fx

float4 DestColor;

texture2D ColorMap;
sampler2D ColorMapSampler = sampler_state
{
    Texture = <ColorMap>;
};

struct PixelShaderInput
{
    float2 TexCoord : TEXCOORD0;
};

float4 PixelShaderFunction(PixelShaderInput input) : COLOR0
{
    float4 srcRGBA = tex2D(ColorMapSampler, input.TexCoord);

    float fmax = max(srcRGBA.r, max(srcRGBA.g, srcRGBA.b));
    float fmin = min(srcRGBA.r, min(srcRGBA.g, srcRGBA.b));
    float delta = fmax - fmin;

    float4 originalDestColor = float4(1, 0, 0, 1);
    float4 deltaDestColor = originalDestColor - DestColor;

    float4 finalRGBA = srcRGBA - (deltaDestColor * delta);

    return finalRGBA;
}

technique Technique1
{
    pass ColorTransform
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
float4颜色;
纹理2D彩色地图;
sampler2D ColorMapSampler=采样器\状态
{
纹理=;
};
结构像素着色器输入
{
浮动2 TexCoord:TEXCOORD0;
};
float4 PixelShaderFunction(PixelShaderInput输入):COLOR0
{
float4 srcRGBA=tex2D(ColorMapSampler,input.TexCoord);
float fmax=max(srcRGBA.r,max(srcRGBA.g,srcRGBA.b));
float fmin=min(srcRGBA.r,min(srcRGBA.g,srcRGBA.b));
浮动增量=fmax-fmin;
float4 originalDestColor=float4(1,0,0,1);
float4 deltaDestColor=originalDestColor-DestColor;
float4 finalRGBA=srcRGBA-(deltaDestColor*delta);
返回finalRGBA;
}
技术1
{
传递颜色变换
{
PixelShader=编译ps_2_0 PixelShaderFunction();
}
}
如果有人能帮我解决这个问题,我将不胜感激
float4 DestColor;

texture2D ColorMap;
sampler2D ColorMapSampler = sampler_state
{
    Texture = <ColorMap>;
};

struct PixelShaderInput
{
    float2 TexCoord : TEXCOORD0;
};

float4 PixelShaderFunction(PixelShaderInput input) : COLOR0
{
    float4 srcRGBA = tex2D(ColorMapSampler, input.TexCoord);

    float fmax = max(srcRGBA.r, max(srcRGBA.g, srcRGBA.b));
    float fmin = min(srcRGBA.r, min(srcRGBA.g, srcRGBA.b));
    float delta = fmax - fmin;

    float4 originalDestColor = float4(1, 0, 0, 1);
    float4 deltaDestColor = originalDestColor - DestColor;

    float4 finalRGBA = srcRGBA - (deltaDestColor * delta);

    return finalRGBA;
}

technique Technique1
{
    pass ColorTransform
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}