Search code examples
xnashadermonogamehlslalphablending

Only do alpha blending on certain output colors


In MonoGame I have a pixel shader that has two output colors.

The first is the regular color drawn to a standard 4-channel 32-bit Color rendertarget.

The second is the z-index drawn to a 1-channel 16-bit HalfSingle rendertarget.

I want to do alpha blending on the first color, but not on the z-index.

Is there a way to do this without declaring a sampler for the underlying texture and doing the alphablending manually?

matrix WorldViewProjection;

Texture2D SpriteTexture;

sampler2D SpriteTextureSampler = sampler_state
{
    Texture = <SpriteTexture>;
};

struct VertexShaderOutput
{
    float4 Position : SV_POSITION;
    float4 Color : COLOR0;
    float2 TextureCoordinates : TEXCOORD0;
    float2 depth : TEXCOORD1;
};

struct PS_OUTPUT
{
    float4 color : COLOR0;
    float4 depth : COLOR1;
};

VertexShaderOutput SpriteVertexShader(float4 position : POSITION0, float2 float4 color : COLOR0, float2 texCoord : TEXCOORD0)
{
    VertexShaderOutput output = (VertexShaderOutput)0;
    output.Position = mul(position, WorldViewProjection);
    output.Color = color;
    output.TextureCoordinates = texCoord;
    output.depth.x = position.z;
    return output;
}

PS_OUTPUT SpritePixelShader(VertexShaderOutput input) : COLOR
{
    PS_OUTPUT output = (PS_OUTPUT)0;
    float4 color = tex2D(SpriteTextureSampler, input.TextureCoordinates) * input.Color;
    output.color = color;
    output.depth.x = input.depth.x;
    return output;
}

technique SpriteDrawing
{
    pass P0
    {
        VertexShader = compile vs_2_0 SpriteVertexShader();
        PixelShader = compile ps_2_0 SpritePixelShader();
    }
};

Solution

  • You can set the alpha of the color you don't want to blend to 1. Here the render target I use for depth does not have an alpha channel, but this still works.

    output.depth.a = 1;