Sign in to follow this  
wh1sp3rik

[solved] Alpha blend problem

Recommended Posts

wh1sp3rik    248
Hello, I am frustated with this problem :) because i can't figure it out .. perhaps, it's missing something in my code. It's DirectX 9, c++. I am working on deferred lighting. One directional light works fine, but if i add another light, always last light is rendered. ////////////////////////// CODE /////////////////////////// void RenderMgr::RenderLights() { WinMgr::d3ddev->SetRenderTarget( 0, RenderMgr::s_LightTexture ); WinMgr::d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0, 0, 0), 1.0f, 0); WinMgr::d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); WinMgr::d3ddev->SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD); WinMgr::d3ddev->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); WinMgr::d3ddev->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE); WinMgr::d3ddev->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, false ); // Render all lights in da scene :) ////////////////////////////////////////////// RenderMgr::RenderDirectionalLight(D3DXVECTOR3(0, 0, 1) , D3DXVECTOR3(0.0, 0.0, 1.0)); RenderMgr::RenderDirectionalLight(D3DXVECTOR3(1, 0, -1) , D3DXVECTOR3(1.0, 0.0, 0.0)); ////////////////////////////////////////////////////////////////////////////////// WinMgr::d3ddev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE); } /////////////// ////////////////////////////////////////////////// and in Directional light, I am rendering quad only with shader from Catalin's XNA tutorial. I tried lots of kinds of blend operations. Normals blend operations works, but there are lots of "bad pixels", i need to use alphablend, but i can set everything, same result :) perhaps, I am missing something important .. if you need additional info, np thank you for helping :) [Edited by - wh1sp3rik on May 5, 2010 2:46:24 PM]

Share this post


Link to post
Share on other sites
Adam_42    3629
I'm just wondering if the first light writes into the z-buffer, and then the second one fails the z test.

Actually the ZFUNC doesn't matter too much, you really want D3DRS_ZWRITEENABLE off for lights. You should also turn D3DRS_ZENABLE off to start with.

Share this post


Link to post
Share on other sites
Adam_42    3629
Doh. I missed the obvious issue, try replacing your state setting code with this:


WinMgr::d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
WinMgr::d3ddev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
WinMgr::d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
WinMgr::d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
WinMgr::d3ddev->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, false );


Note that if D3DRS_SEPARATEALPHABLENDENABLE is disabled none of the other alpha channel blending states are used.

If that still looks wrong, a screenshot might be helpful.

Share this post


Link to post
Share on other sites
wh1sp3rik    248
So .. Screen looks like this, when i have only one light

ftp://78.102.70.147/tempimg/bluelight.png

When i add second red light

ftp://78.102.70.147/tempimg/redlight.png

and when i use your code

ftp://78.102.70.147/tempimg/result.png

so, you can see, specular missing + nothing is blended.
hmm :) strange thing is, it affected my images on the left side, lol .. because blending is off in this place

Share this post


Link to post
Share on other sites
Adam_42    3629
You might want to try debugging it with PIX. That will let you examine what's going on in detail.

Also does the RenderDirectionalLight() function change any render states?

Share this post


Link to post
Share on other sites
wh1sp3rik    248
this is DL function

void RenderMgr::RenderDirectionalLight( D3DXVECTOR3 lightDir, D3DXVECTOR3 color )
{
// Get transormations
D3DXMATRIXA16 matView, matProj, matViewProj, matViewProjInv;
WinMgr::d3ddev->GetTransform(D3DTS_VIEW, &matView);
WinMgr::d3ddev->GetTransform(D3DTS_PROJECTION, &matProj);
matViewProj = matView * matProj; D3DXMatrixInverse( &matViewProjInv, NULL, &matViewProj);

// Set Shader parameters
RenderMgr::DirectionalLightEffect->SetTexture("colorMap", RenderMgr::t_ColorTexture );
RenderMgr::DirectionalLightEffect->SetTexture("normalMap", RenderMgr::t_NormalTexture );
RenderMgr::DirectionalLightEffect->SetTexture("depthMap", RenderMgr::t_DepthTexture );

RenderMgr::DirectionalLightEffect->SetValue("lightDirection", lightDir, sizeof( D3DXVECTOR3 ));
RenderMgr::DirectionalLightEffect->SetValue("Color", color, sizeof( D3DXVECTOR3 ) );
RenderMgr::DirectionalLightEffect->SetValue("cameraPosition", CamMgr::CameraList[0]->position ,sizeof( D3DXVECTOR3 ) );
RenderMgr::DirectionalLightEffect->SetMatrix("InvertViewProjection", &matViewProjInv);
RenderMgr::DirectionalLightEffect->SetValue("halfPixel", D3DXVECTOR2( 0.5f / WinMgr::Width, 0.5f / WinMgr::Height ), sizeof( D3DXVECTOR2 ));

RenderMgr::RenderQuad( RenderMgr::DirectionalLightEffect );
}




and this is RenderQuad function.
void RenderMgr::RenderQuad(LPD3DXEFFECT effect)
{
WinMgr::d3ddev->SetRenderState(D3DRS_ZENABLE, false );

D3DXMATRIX EmptyMatrix; D3DXMatrixIdentity( &EmptyMatrix );
WinMgr::d3ddev->SetTransform( D3DTS_WORLD, &EmptyMatrix );


WinMgr::d3ddev->BeginScene();
if (SUCCEEDED(effect->SetTechnique("Technique1")))
{
UINT passes;
if (SUCCEEDED(effect->Begin(&passes,0)))
{
for (int i=0;i<passes;i++)
{
effect->BeginPass(i);
WinMgr::d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
WinMgr::d3ddev->SetStreamSource(0, vertexbuffer, 0, sizeof(SCREEN_VERTEX));
WinMgr::d3ddev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(SCREEN_VERTEX));
effect->EndPass();
}
effect->End();
}
}
WinMgr::d3ddev->EndScene();
WinMgr::d3ddev->SetRenderState(D3DRS_ZENABLE, true );
}

so, I am changing only ZENABLE for screenquad.

About PIX: I tried it, but i don't know, how to use it right. i can only get functions, which i called :) is there any tutorial fo PIX ?

Share this post


Link to post
Share on other sites
scope    108
did you try setting the states in the shader?


cullMode = CCW;
AlphaBlendEnable = TRUE;
SRCBLEND = ONE;
DESTBLEND = ONE;
zWriteEnable = false;
zEnable = false;

Share this post


Link to post
Share on other sites
wh1sp3rik    248
strange :) normal blending seems working, but there is a problem with alpha = pixel artefacts.

i would like to make this function

result.r = color1.r * 1 + color2.r * 1
result.g = color1.g * 1 + color2.g * 1
result.b = color1.b * 1 + color2.b * 1
result.a = color1.a * 1 + color2.a * 1

if I am I right, hehe :)

i can use another shader for this operation, but i think, It's a waste of application speed, what do you think ?



[Edited by - wh1sp3rik on May 5, 2010 2:16:41 PM]

Share this post


Link to post
Share on other sites
wh1sp3rik    248
hehe, so, i solved my problem :)

WinMgr::d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
WinMgr::d3ddev->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true );

WinMgr::d3ddev->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
WinMgr::d3ddev->SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
WinMgr::d3ddev->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE);

WinMgr::d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
WinMgr::d3ddev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
WinMgr::d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

this is what i did :) i blend RGB and Alpha separately :)
:) thanks for helping and giving me ideas :)

Share this post


Link to post
Share on other sites

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