C Board  

Go Back   C Board > General Programming Boards > Game Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 07-04-2009, 06:16 PM   #1
Registered User
 
Join Date: Oct 2008
Posts: 72
Direct3D Alpha Blend with Lighting ?

Hi,

I was working with the microsoft shadow volume demo and I was trying to modify the alpha blending states so that i could load a png with a transparent background. I am trying to texture it onto a 3D model. It works fine but the moment I turn the lights on, the transparent background starts to become visible.

My blending states are like this

Code:
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
I am using the microsoft shadow volume demo and did not write the lighting shader myself but I believe it is per pixel lighting. I have attached the shader.

Could someone please let me know how I can maintain the transparency of the png when the lights are turned on ?

Also, does anyone know if theres a way to ignore black pixels or to conduct a color key without using the LoadTextureFromFile method ?

Any help is appreciated.
Thank You.
Attached Files
File Type: txt ShadowVolume.fx.txt (11.5 KB, 82 views)
rocketman03 is offline   Reply With Quote
Old 07-05-2009, 12:47 AM   #2
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,470
Code:
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
Should be:
Code:
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
If the alpha value is not exactly 0 then you will see the quad around the object albeit very faint.
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Old 07-05-2009, 01:22 AM   #3
Registered User
 
Join Date: Oct 2008
Posts: 72
Thank you for your reply. I tried it but I'm still getting the same result. I've checked the file has an alpha of zero and It works fine as long as the lights are off. As soon as I turn on a light and its within the range of the png..I start to see a quad fading in as I turn on more lights.

I'm guessing that the quad is still there even though its not being rendered, so when it comes in range of the light, it gets lit up causing its alpha to change.

Is there any way to make the light not affect transparent pixels ? Please let me know ?

Thanks!
rocketman03 is offline   Reply With Quote
Old 07-05-2009, 09:31 AM   #4
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,470
It should not affect transparent pixels. Lighting has nothing to do with transparency. Transparency is figured out at the rasterization level. If you have the alpha set to 0 for transparent then those two render states should work. Alpha has nothing to do with lighting.

Perhaps you should post the shader code - most importantly the pixel shader since per-pixel lighting will be done there.
__________________
If you aim at everything you will hit something but you won't know what it is.

Last edited by Bubba; 07-05-2009 at 10:16 AM.
Bubba is offline   Reply With Quote
Old 07-05-2009, 12:23 PM   #5
Registered User
 
Join Date: Oct 2008
Posts: 72
Oh..I see,I dont know why its not working then. I attached the shader in the first post. The only techniques being used are the renderscene and rendercsene ambient. Could you please let me know theres something in it which is causing this ? I haven't done much shader programming before and not quite sure how it works!..thank you!

here is the main code for computing the ligthting..

Code:
void VertSceneAmbient( float4 vPos : POSITION,
                       float2 vTex0 : TEXCOORD0,
                       out float4 oPos : POSITION,
                       out float2 oTex0 : TEXCOORD0 )
{
    // Transform the position from object space to homogeneous projection space
    oPos = mul( vPos, g_mWorldViewProjection );

    // Just copy the texture coordinate through
    oTex0 = vTex0;
}


float4 PixSceneAmbient( float2 Tex0 : TEXCOORD0 ) : COLOR0
{
    // Lookup mesh texture and modulate it with material and ambient amount
    return g_vAmbient * tex2D( g_samScene, Tex0 ) * g_vMatColor;
}


void VertScene( float4 vPos : POSITION,
                float3 vNormal : NORMAL,
                f

Last edited by Bubba; 07-05-2009 at 09:23 PM.
rocketman03 is offline   Reply With Quote
Old 07-05-2009, 09:24 PM   #6
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,470
Could you please repost with code tags? I tried to add them but my internet locked up during the submit. It obviously did not send all of the data during the lock up b/c it messed your original post up.
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Old 07-05-2009, 09:32 PM   #7
Registered User
 
Join Date: Oct 2008
Posts: 72
Oh, I am extremely sorry. Here is the edited version
Code:
void VertSceneAmbient( float4 vPos : POSITION,
float2 vTex0 : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTex0 : TEXCOORD0 )
{
            // Transform the position from object space to homogeneous projection space
           oPos = mul( vPos, g_mWorldViewProjection );

           // Just copy the texture coordinate through
           oTex0 = vTex0;
}


float4 PixSceneAmbient( float2 Tex0 : TEXCOORD0 ) : COLOR0
{
      // Lookup mesh texture and modulate it with material and ambient amount
      return g_vAmbient * tex2D( g_samScene, Tex0 ) * g_vMatColor;
}


void VertScene( float4 vPos : POSITION,
float3 vNormal : NORMAL,
float2 vTex0 : TEXCOORD0,
out float4 oPos : POSITION,
out float4 ViewPos : TEXCOORD0,
out float3 ViewNormal : TEXCOORD1,
out float2 oTex0 : TEXCOORD2,
out float4 oDiffuse : TEXCOORD3 )
{
     // Transform the position from view space to homogeneous projection space
      oPos = mul( vPos, g_mWorldViewProjection );
// Compute view space position ViewPos = mul( vPos, g_mWorldView ); // Compute world space normal ViewNormal = normalize( mul( vNormal, (float3x3)g_mWorldView ) ); // Modulate material with light to obtain diffuse oDiffuse = g_vMatColor * g_vLightColor; // Just copy the texture coordinate through oTex0 = vTex0;
} float4 PixScene( float4 ViewPos : TEXCOORD0, float3 ViewNormal : TEXCOORD1, float2 Tex0 : TEXCOORD2, float4 Diffuse : TEXCOORD3 ) : COLOR0 {
// Pixel to light vector float3 L = g_vLightView - ViewPos; float LenSq = dot( L, L ); L = normalize( L ); // Compute lighting amount float4 I = saturate( dot( normalize( ViewNormal ), L ) ) * Diffuse * (LIGHT_FALLOFF * LIGHT_FALLOFF) / LenSq; // Lookup mesh texture and modulate it with diffuse // return float4( tex2D( g_samScene, Tex0 ).xyz, 1.0f ) * I; float4 returnColor = tex2D( g_samScene, Tex0 ); returnColor.rgb *= I; return returnColor;
} technique RenderScene {pass P0{
VertexShader = compile vs_2_0 VertScene(); PixelShader = compile ps_2_0 PixScene(); ZEnable = true; ZFunc = LessEqual; StencilEnable = true; AlphaBlendEnable = true; BlendOp = Add; SrcBlend = SrcAlpha; DestBlend = InvSrcAlpha; StencilRef = 1; StencilFunc = Greater; StencilPass = Keep;
} }

Last edited by rocketman03; 07-05-2009 at 09:36 PM.
rocketman03 is offline   Reply With Quote
Old 07-06-2009, 12:11 AM   #8
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,470
The pixel shader is doing standard cosine lighting and standard falloff calculations.

This:
Code:
returnColor.rgb *= I;
...looks a bit suspect. The commented line above it is even more suspect since it will always return 1.0f in alpha if the alpha in the diffuse is 1.0f.

Try multiplying returnColor by I but don't specify which components to multiply.

Code:
...
return returnColor * I;
This should return:

float4(returnColor.r * I.r,returnColor.g * I.g,returnColor.b * I.b,returnColor.a * I.a);

Therefore if returnColor or more appropriately the source texture alpha is 0.0f and diffuse alpha is 1.0f you will get a returnColor alpha of 0.0f. The only condition in which you will get a non-zero alpha in returnColor is if both source color alpha is non-zero and diffuse color alpha is non-zero. Any other combination will yield zero alpha.

I'm also assuming you are using ID3DXEffect and are allowing it to handle the state changes. You can tell ID3DXEffect to not save state changes. In this case you would want to ensure that alpha testing was off otherwise you will get incorrect results. Make sure that alpha test and alpha blend are never both enabled at the same time.
__________________
If you aim at everything you will hit something but you won't know what it is.

Last edited by Bubba; 07-06-2009 at 12:15 AM.
Bubba is offline   Reply With Quote
Old 07-06-2009, 01:00 AM   #9
Registered User
 
Join Date: Oct 2008
Posts: 72
Oh..I see..Thank you so much!..although..I'm still seeing a translucent quad when I have more than 6 lights on(it becomes more opaque as I turn more Lights on)..I havent set the effect file not to save the state..I'll try that..although I dont see an alpha test anywhere..the only techniques being passes are..

Code:
technique RenderScene
{
    pass P0
    {
        VertexShader = compile vs_2_0 VertScene();
        PixelShader  = compile ps_2_0 PixScene();
        ZEnable = true;
        ZFunc = LessEqual;
        StencilEnable = true;
        
        AlphaBlendEnable = true;
        BlendOp = Add;
        SrcBlend = SrcAlpha;
        DestBlend = InvSrcAlpha;
                
        StencilRef = 1;
        StencilFunc = Greater;
        StencilPass = Keep;
    }
}
and..

Code:
technique RenderSceneAmbient
{
    pass P0
    {
        VertexShader = compile vs_2_0 VertSceneAmbient();
        PixelShader  = compile ps_2_0 PixSceneAmbient();
        StencilEnable = false;
        ZFunc = LessEqual;
                
    }
}
The code works with upto 4 lights(basically when png is not in the radius of the lights)..but its still affected when the lights are in range..is this because of the state changes ?
rocketman03 is offline   Reply With Quote
Old 07-07-2009, 03:02 PM   #10
Registered User
 
Join Date: Oct 2008
Posts: 72
After removing the ZFunc = LessEqual , I am getting full transparency when the lights are in front of the model. But when I turn on the lights behind the model, I start seeing the quad again. Do you know what could be causing this ?

Thank you!
rocketman03 is offline   Reply With Quote
Old 07-07-2009, 04:04 PM   #11
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,470
You should be rendering these in back to front order anyways. The only thing I could think of would be back lighting when the wrong side of the poly is lit, but your formula in the pixel shader would still return an alpha of 0.0f.
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
How to map enums to their string representation globaly? pheres C++ Programming 23 07-09-2007 04:49 AM
D3DXSprite and alpha blend Magos Game Programming 1 05-23-2006 04:55 AM
Lighting in Managed Direct3d Rune Hunter Game Programming 0 04-30-2006 07:40 AM
Lighting a Direct3D 9 mesh sphere bennyandthejets Game Programming 12 02-14-2005 01:19 AM
Creating a 2D GUI using Direct3D codec Game Programming 8 09-23-2004 11:57 AM


All times are GMT -6. The time now is 05:46 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22