Question

For an academic project I'm trying to write a code for drawing billboards from scratch; now I'm at the point of making them translucent. I've managed to make them look good against the background but they still may cover each other with their should-be-transparent corners, like in this picture:

I'm not sure what I'm doing wrong. This is the effect file I'm using to draw the billboards. I've omitted the parts related to the vertex shader, which I think is irrelevant right now.

//cut

texture Texture;
texture MaskTexture;

sampler Sampler = sampler_state
{
    Texture = (Texture);

    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Point;

    AddressU = Clamp;
    AddressV = Clamp;
};

sampler MaskSampler = sampler_state
{
    Texture = (MaskTexture);

    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Point;

    AddressU = Clamp;
    AddressV = Clamp;
};

//cut

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 Color : COLOR;
    float2 TexCoord : TEXCOORD0;
};

//cut

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    float4 result = tex2D(Sampler, input.TexCoord) * input.Color;
    float4 mask = tex2D(MaskSampler, input.TexCoord);
    float alpha = mask.r;
    result.rgb *= alpha;
    result.a = alpha;
    return result;
}

technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();

        AlphaBlendEnable = true;
        SrcBlend = SrcAlpha;
        DestBlend = InvSrcAlpha;
    }
}

I've got two textures, named Texture and MaskTexture, the latter being in grayscale. The billboards are, most likely, in the same vertex buffer and are drawn with a single call of GraphicsDevice.DrawIndexedPrimitives() from XNA.

I've got a feeling I'm not doing the whole thing right.

Was it helpful?

Solution 2

I have found a solution. The shaders are fine, the problem turned out to be in the XNA code, so sorry for drawing your attention to the wrong thing.

The solution is to enable a depth stencil buffer (whatever it is) before drawing the billboards:

device.DepthStencilState = DepthStencilState.DepthRead;

It can be disabled afterwards:

device.DepthStencilState = DepthStencilState.Default;

OTHER TIPS

You have to draw them in order. From farthest to closest.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top