透明物体互相覆盖

时间:2012-06-13 18:47:00

标签: graphics 3d xna hlsl pixel-shader

对于一个学术项目,我正在尝试编写一个从头开始绘制广告牌的代码;现在我正处于让它们变得半透明的地步。我已经设法使它们在背景下看起来很好但是它们仍然可以用它们应该是透明的角落来互相覆盖,就像在这张图片中一样:

我不确定我做错了什么。这是我用来绘制广告牌的效果文件。我省略了与顶点着色器相关的部分,我认为这与现在无关。

//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;
    }
}

我有两个纹理,名为Texture和MaskTexture,后者是灰度。广告牌很可能位于同一个顶点缓冲区中,只需从XNA调用GraphicsDevice.DrawIndexedPrimitives()即可绘制。

我有一种感觉,我没有做正确的事情。

2 个答案:

答案 0 :(得分:0)

你必须按顺序绘制它们。从最远到最近。

答案 1 :(得分:0)

我找到了解决方案。着色器很好,问题原来是在XNA代码中,所以很抱歉引起你注意错误的事情。

解决方案是在绘制广告牌之前启用深度模板缓冲区(无论它是什么):

device.DepthStencilState = DepthStencilState.DepthRead;

之后可以禁用它:

device.DepthStencilState = DepthStencilState.Default;