C# 如何在一批sprite中仅应用一次技术?

C# 如何在一批sprite中仅应用一次技术?,c#,xna,directx,xna-4.0,hlsl,C#,Xna,Directx,Xna 4.0,Hlsl,问题是,当我尝试在sprite批处理中绘制上一个渲染目标的纹理时,每个过程都被应用。在sprite批处理中应用过程似乎不起作用 我发现的一个解决方案是将每个过程移动到它自己的技术中,但这并不是应该实现多过程效果的方式。如何在一批sprite中仅应用一次技术 我正在尝试使用阴影和高光绘制窗口边框的多通道效果 在Pass0中,顶点缓冲区设置为形状中的顶点。顶点着色器将顶点转换为屏幕空间,像素着色器使用FillColor填充形状 在Pass1中,第一个过程中的渲染目标用于此过程的像素着色器。现在,它只

问题是,当我尝试在sprite批处理中绘制上一个渲染目标的纹理时,每个过程都被应用。在sprite批处理中应用过程似乎不起作用

我发现的一个解决方案是将每个过程移动到它自己的技术中,但这并不是应该实现多过程效果的方式。如何在一批sprite中仅应用一次技术

我正在尝试使用阴影和高光绘制窗口边框的多通道效果

在Pass0中,顶点缓冲区设置为形状中的顶点。顶点着色器将顶点转换为屏幕空间,像素着色器使用FillColor填充形状

在Pass1中,第一个过程中的渲染目标用于此过程的像素着色器。现在,它只是将其设置为用于调试的颜色。最后利用TEXCOORDn语义和采样器得到相邻像素的颜色

最后一个过程Pass2与Pass1完全相同,只是它检查不同的颜色并在阴影下放置高光

Window.cs Window::Draw

window.fx

public void Draw(MainGame game) {
    Matrix vp = game.view * projection;
    game.GraphicsDevice.SetRenderTarget(target[0]);
    game.GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 0, 0);
    game.GraphicsDevice.SetVertexBuffer(vertexbuffer);
    game.effect.Parameters["VPMatrix"].SetValue(vp);
    game.effect.Parameters["FillColor"].SetValue(new float[] { 103, 103, 103, 255 });
    game.effect.CurrentTechnique = game.effect.Techniques["Border"];
    game.effect.CurrentTechnique.Passes[0].Apply();
    game.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);

    game.GraphicsDevice.SetRenderTarget(target[1]);
    game.GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 0, 0);
    game.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise, game.effect);
    game.effect.CurrentTechnique.Passes[1].Apply();
    game.spriteBatch.Draw(target[0], Vector2.Zero, Color.White);
    game.spriteBatch.End();

    game.GraphicsDevice.SetRenderTarget(target[0]);
    game.GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 0, 0);
    game.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise, game.effect);
    game.effect.CurrentTechnique.Passes[2].Apply();
    game.spriteBatch.Draw(target[1], Vector2.Zero, Color.White);
    game.spriteBatch.End();

    game.GraphicsDevice.SetRenderTarget(game.backBuffer);
    game.spriteBatch.Begin();
    game.spriteBatch.Draw(target[0], rectangle, Color.White);
    game.spriteBatch.End();
}
float4x4 VPMatrix : register(c0);
float4 FillColor : register(c4);
float2 SHPercent : register(c5) = { 0.36893203883495145631067961165049, 1.262135922330097087378640776699 };
sampler ShapeSampler : register(s0) = sampler_state{ };

struct Fill_VS_Input {
    float4 position : POSITION0;
};

struct Fill_PS_Input {
    float4 position : POSITION0;
};

struct Shadow_PS_Input {
    float4 position : TEXCOORD0;
};

struct Highlight_PS_Input {
    float4 position : TEXCOORD0;
};

float4 ClampColor(float4 color) {
    return float4(color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
}

float4 ShiftValue(float4 color, float percent) {
    return float4(clamp(color[0] * percent, 0, 1), clamp(color[1] * percent, 0, 1), clamp(color[2] * percent, 0, 1), 1);
}

Fill_PS_Input Fill_VS(Fill_VS_Input input) {
    Fill_PS_Input output;
    output.position = mul(input.position, VPMatrix);
    return output;
}

float4 Fill_PS(Fill_PS_Input input) : COLOR0 {
    return ClampColor(FillColor);
}

float4 Shadow_PS(Shadow_PS_Input input) : COLOR0 {
    if (tex2D(ShapeSampler, float2(input.position.x, input.position.y))[3] == 0)
        return float4(0, 255, 0, 255);

    /*if (input.position.x == 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (input.position.x == 1)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (input.position.y == 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (input.position.y == 1)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (tex2D(ShapeSampler, float2(input.position.x, input.position.y - 1))[3] = 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (tex2D(ShapeSampler, float2(input.position.x + 1, input.position.y))[3] = 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (tex2D(ShapeSampler, float2(input.position.x, input.position.y + 1))[3] = 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);

    if (tex2D(ShapeSampler, float2(input.position.x - 1, input.position.y))[3] = 0)
        return ShiftValue(ClampColor(FillColor), SHPercent[0]);*/

    return float4(255, 0, 0, 255);
}

float4 Highlight_PS(Highlight_PS_Input input) : COLOR0 {
    return tex2D(ShapeSampler, float2(input.position.x, input.position.y)).rbga;
}

technique Border {
    pass Pass0 {
        VertexShader = compile vs_2_0 Fill_VS();
        PixelShader = compile ps_2_0 Fill_PS();
    }

    pass Pass1 {
        PixelShader = compile ps_2_0 Shadow_PS();
    }

    pass Pass2 {
        PixelShader = compile ps_2_0 Highlight_PS();
    }
}