Sign in to follow this  

Alpha Blend Enabled Not Working XNA

This topic is 3590 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have some lights i need to draw in. So i added multiple passes to my HLSL technique. When the screen renders I get all the light but everything else kind of transparent. Free Image Hosting at www.ImageShack.us Here is the code i'm using XNA Draw:
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.Blue);

            graphics.GraphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Wrap;
            graphics.GraphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Wrap;

            Matrix rotationMatrix = Matrix.CreateRotationY(cameraYaw);

            Vector3 headOffset = Vector3.Transform(avatarHeadOffset, rotationMatrix);

            Vector3 cameraPosition = avatarPosition + headOffset;

            Vector3 transformedReference = Vector3.Transform(cameraReference, rotationMatrix);

            Vector3 cameraLookat = transformedReference + cameraPosition;

            Matrix slookAt = Matrix.CreateLookAt(cameraPosition, cameraLookat, Vector3.Up);

            Matrix[] llookAt = new Matrix[4];
            Matrix lProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(phi), graphics.GraphicsDevice.Viewport.AspectRatio, 0.1f, 5000f);

            for (int i = 0; i < 4; i++)
            {
                Vector3 lLook = lightPosition[i] + Vector3.Down;
                llookAt[i] = Matrix.CreateLookAt(lightPosition[i], lLook, Vector3.Forward);
            }

            graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true;
            graphics.GraphicsDevice.RenderState.SourceBlend = Blend.One;
            graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.One;

            DrawObejcts("ShadowedScene", slookAt, buildingModel, Matrix.Identity, llookAt, lProjection);

            base.Draw(gameTime);

        }


void DrawObejcts(string techniqueName, Matrix lookAt, Model model, Matrix world, Matrix[] lView, Matrix lProjection)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            roomLighting.CurrentTechnique = roomLighting.Techniques[techniqueName];
            roomLighting.Parameters["View"].SetValue(lookAt);
            roomLighting.Parameters["LightView"].SetValue(lView);
            roomLighting.Parameters["LightProjection"].SetValue(lProjection);
            roomLighting.Parameters["Projection"].SetValue(Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), graphics.GraphicsDevice.Viewport.AspectRatio, 0.1f, 5000f));
            roomLighting.Parameters["lightPosition"].SetValue(lightPosition);
            roomLighting.Parameters["lightDirection"].SetValue(Vector3.Down);
            roomLighting.Parameters["phi"].SetValue(MathHelper.ToRadians(phi));
            roomLighting.Parameters["theta"].SetValue(MathHelper.ToRadians(theta));
            roomLighting.Parameters["cphi"].SetValue(Convert.ToSingle(Math.Cos(MathHelper.ToRadians(phi))));
            roomLighting.Parameters["ctheta"].SetValue(Convert.ToSingle(Math.Cos(MathHelper.ToRadians(theta))));
            roomLighting.Parameters["dimFactor"].SetValue(dimFactor);
            roomLighting.Parameters["lightsOn"].SetValue(lightsOn);
            roomLighting.Parameters["maxDepth"].SetValue(164.0f);
            roomLighting.Parameters["shadowMap0"].SetValue(shadowMap0);
            roomLighting.Parameters["shadowMap1"].SetValue(shadowMap1);
            roomLighting.Parameters["shadowMap2"].SetValue(shadowMap2);
            roomLighting.Parameters["shadowMap3"].SetValue(shadowMap3);

            int i = 0;
            foreach (ModelMesh mesh in model.Meshes)
            {
                roomLighting.Parameters["World"].SetValue(transforms[mesh.ParentBone.Index] * world);

                if (techniqueName.Equals("SpotLight") || techniqueName.Equals("ShadowedScene"))
                {

                    foreach (Effect b in mesh.Effects)
                    {
                        roomLighting.Parameters["modelTexture"].SetValue((Texture2D)textures[i]);
                        i++;
                    }
                }

                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                {
                    graphics.GraphicsDevice.Vertices[0].SetSource(mesh.VertexBuffer, meshPart.StreamOffset, meshPart.VertexStride);
                    graphics.GraphicsDevice.VertexDeclaration = meshPart.VertexDeclaration;
                    graphics.GraphicsDevice.Indices = mesh.IndexBuffer;

                    roomLighting.Begin(SaveStateMode.None);
                    foreach (EffectPass pass in roomLighting.CurrentTechnique.Passes)
                    {
                        pass.Begin();
                        graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, meshPart.BaseVertex, 0, meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount);
                        pass.End();
                    }
                    roomLighting.End();
                }
                mesh.Draw();
            }
        }


HLSL:
struct SSceneVertexToPixel
{
    float4 Position             : POSITION;
    float4 ShadowMapSamplingPos : TEXCOORD0;    
    float4 RealDistance			: TEXCOORD1;
	float2 TexCoords            : TEXCOORD2;
	float3 Normal				: TEXCOORD3;
	float3 Position3D           : TEXCOORD4;
	float3 interPos				: TEXCOORD5;
};

struct SScenePixelToFrame
{
    float4 Color : COLOR0;
};

struct SSceneVertexInput
{
	float4 inPos : POSITION;
	float2 inTexCoords : TEXCOORD0;
	float3 inNormal : NORMAL;
};
SSceneVertexToPixel ShadowedSceneVertexShader(SSceneVertexInput input, uniform int currentLight)
{
    SSceneVertexToPixel Output = (SSceneVertexToPixel)0;
    float4x4 wvp =  mul(mul(World, View), Projection);
    Output.Position = mul(input.inPos, wvp);


	float4x4 lwvp =  mul(mul(World, LightView[currentLight]), LightProjection);
	Output.ShadowMapSamplingPos = mul(input.inPos,lwvp );
	Output.RealDistance = Output.ShadowMapSamplingPos.z/maxDepth; 
    Output.Normal = normalize(mul(input.inNormal, (float3x3)World));
    Output.Position3D = mul(input.inPos, World);

    Output.TexCoords = input.inTexCoords;

    return Output;    
}

SScenePixelToFrame ShadowedScenePixelShader(SSceneVertexToPixel PSIn, uniform int currentLight)
{
    SScenePixelToFrame Output = (SScenePixelToFrame)0;

	float3 lightDir= normalize(lightDirection);
	float4 FinalColor;// = {0.0f,0.0f,0.0f,1.0f};	
			

		float2 ProjectedTexCoords;

		ProjectedTexCoords[0] = PSIn.ShadowMapSamplingPos.x/PSIn.ShadowMapSamplingPos.w/2.0f +0.5f;
		ProjectedTexCoords[1] = -PSIn.ShadowMapSamplingPos.y/PSIn.ShadowMapSamplingPos.w/2.0f +0.5f;
		if ((saturate(ProjectedTexCoords.x) == ProjectedTexCoords.x) && (saturate(ProjectedTexCoords.y) == ProjectedTexCoords.y))
		{    
			float StoredDepthInShadowMap = tex2D(ShadowMapSamplers[currentLight], ProjectedTexCoords).x;    
			if ((PSIn.RealDistance.x - 1.0f/100.0f) <= StoredDepthInShadowMap)    
			{						
				float4 ColorComponent =tex2D(ColoredTextureSampler, PSIn.TexCoords);		
				float3 lightVec = lightPosition[currentLight] - PSIn.Position3D.xyz;
				lightVec= normalize(lightVec);	
				float diffuse = dot(PSIn.Normal, lightVec);
				float cAlpha = dot(-lightDir,lightVec);	
				if (cAlpha >= cphi && cAlpha <= ctheta)
				{
					FinalColor = CalculateFallOff(cAlpha) * ColorComponent;
				}
				else if (cAlpha >= ctheta)
				{
					FinalColor =  ColorComponent;
				}
	           
				Output.Color = FinalColor * diffuse;     
				Output.Color.a= 1.0f;  
			}       
		}    

    return Output;
}

technique ShadowedScene
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 ShadowedSceneVertexShader(0);
        PixelShader = compile ps_2_0 ShadowedScenePixelShader(0);
    }
    pass Pass1
    {
        VertexShader = compile vs_2_0 ShadowedSceneVertexShader(1);
        PixelShader = compile ps_2_0 ShadowedScenePixelShader(1);
    }
    pass Pass2
    {
        VertexShader = compile vs_2_0 ShadowedSceneVertexShader(2);
        PixelShader = compile ps_2_0 ShadowedScenePixelShader(2);
    }
    pass Pass3
    {
        VertexShader = compile vs_2_0 ShadowedSceneVertexShader(3);
        PixelShader = compile ps_2_0 ShadowedScenePixelShader(3);
    }
}


Any help would be greatly appreciated.

Share this post


Link to post
Share on other sites
It looks like you're having some blending issues [smile]. The first problem here is that when you always have additive blending enabled, what you render won't blend with your blue background color correctly. Think about it: when you clear to blue, your back-buffer pixels all have the value <0,0,1>. Then what happens when you render something that comes out to say...<1,0,0>? You add those values together, and you get purple <1,0,1>. Or even worse, what happens when you render something that comes out to be all black? Your result is <0,0,1>. Hence your scene looking "transparent", as the black areas come out to blue and white areas come out to be white (<1,1,1> + <0,0,1> = <1,1,1> when clamped to the 0-1 range).

Your other problem is that your objects in the scene will blend with each other, even though they're opaque. See that chair in the foreground that looks transparent? If you render the table behind it first and then the chair second, the table won't be z-culled and they'll both be rendered their results all summed together in the back-buffer.

Your options are

a) Render your first pass for each object without blending, then render your subsequent passes with blending

or

b) Clear to black every frame, and use a z-prepass to ensure that only visible pixels are actually drawn to be back-buffer. This means you render all your objects in your scene with color writes off and z-writes enabled, then in your "real" pass all non-visible pixels are culled and you don't have to worry about them blending together.



Hope this helps. Let me know if you want me to explain anything more clearly.

Share this post


Link to post
Share on other sites
Thanks for the explanation. I went with the first option you gave. Here is the result:

Free Image Hosting at www.ImageShack.us

This is what the code looked like after:


technique ShadowedScene
{
pass Pass0
{
ALPHABLENDENABLE = false;
VertexShader = compile vs_2_0 ShadowedSceneVertexShader(0);
PixelShader = compile ps_2_0 ShadowedScenePixelShader(0);
}
pass Pass1
{
ALPHABLENDENABLE = true;
SRCBLEND = one;
DESTBLEND = one;
VertexShader = compile vs_2_0 ShadowedSceneVertexShader(1);
PixelShader = compile ps_2_0 ShadowedScenePixelShader(1);
}
pass Pass2
{
ALPHABLENDENABLE = true;
SRCBLEND = one;
DESTBLEND = one;
VertexShader = compile vs_2_0 ShadowedSceneVertexShader(2);
PixelShader = compile ps_2_0 ShadowedScenePixelShader(2);
}
pass Pass3
{
ALPHABLENDENABLE = true;
SRCBLEND = one;
DESTBLEND = one;
VertexShader = compile vs_2_0 ShadowedSceneVertexShader(3);
PixelShader = compile ps_2_0 ShadowedScenePixelShader(3);
}
}



I also had to make sure the passes in the shadow map technique turned off alphablendenable using:

ALPHABLENDENABLE = false;

Share this post


Link to post
Share on other sites

This topic is 3590 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this