2012-06-13 26 views
0

对于一个学术项目,我试图写一个从头开始画广告牌的代码;现在我正在让它们变得半透明。我已经成功地使它们看起来映衬不错,但他们仍然可以互相掩护他们应该-是透明的角落,像这样的画面:透明的物体覆盖彼此

我不知道我做错了。这是我用来绘制广告牌的效果文件。我已经省略了与顶点着色器有关的部分,我认为它现在是不相关的。

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

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

我有一种感觉,我没有把整个事情做对。

+0

是否启用GL_BLEND?请看这里的GL_BLEND部分http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml – Ani

+0

@ananthonline对不起,我隐藏了项目在XNA中的信息,而不是OpenGL,在某处帖子结尾。那么,实际上我所做的唯一一件事(或者至少可以记得这样做)来启用混合,就是将'AlphaBlendEnable = true;'添加到'pass'块。这不够吗? – kamilk

+0

我实际上看不到您的HLSL有什么问题,请尝试更改像素着色器,以仅返回从面罩纹理中获取的值,以确保它以您打算使用的方式使用。您的backbuffer格式又是什么? – Andy

回答

0

我找到了解决办法。着色器很好,问题原来是在XNA代码中,所以很抱歉把你的注意力引向错误的东西。

的解决方案是绘制广告牌前启用深度模板缓存(不管它是什么):

device.DepthStencilState = DepthStencilState.DepthRead; 

可以事后禁用:

device.DepthStencilState = DepthStencilState.Default; 
0

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