Jump to content
  • Advertisement
Sign in to follow this  
anders211

Enable Z buffer only for ALPHA CHANNEL > 0

This topic is 919 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

Hi

Firstly please look at the attached image so You would know what my question is.

 

OK, as we see we have goalnet and behind goalnet there is some football player. There is issue that this player is before the net, not behind as it should be. This is because when I was drawing the net I disabled Z buffer. Without disabling Z buffer actually player wouldn't be visible at all.

Is any way to disable Z buffer only for pixel for which mapped texture .dds has alpha>0 and having enable Z buffer for pixel for which mapped texture dds alpha=0? In this way I think the results would be satisfied. My net is created from dds texture.

 

    d3d::pDev->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);
    d3d::pDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    d3d::pDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    d3d::pDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    d3d::pDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    d3d::pDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    d3d::pDev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);


    mGoalnet.drawMesh(mMatOrientation); //draw net


    //restore z buffor
    d3d::pDev->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
    d3d::pDev->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
    d3d::pDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
Edited by anders211

Share this post


Link to post
Share on other sites
Advertisement

Enable Z buffer and use "discard" in your shader, also known as alpha-testing.

 

Here is info about alpha testing in D3D9:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb172254%28v=vs.85%29.aspx

 

(Note that if you want the edges of the net to be partly transparent but not completely, or if you want the net to instead be colored partly transparent glass or similar this solution won't help, so in that case you need to draw all opaque geometry like the player first, and then as the final step in your rendering process draw all alpha-blended surfaces sorted back to front).

Edited by Erik Rufelt

Share this post


Link to post
Share on other sites

Let's assume my alpha channels are 1 or 0 and there is none partly transparency. I used fixed function pipeline.

So I don't know how to realize that in this way:

Enable Z buffer and use "discard" in your shader, also known as alpha-testing.

 

 

As far as using shader instead of fixed function pipeline I have some idea which maybe helps. Z buffer is enabled. In pixel shader when I draw net I should check what is apha color of pixel which is about to be drawn. If aplha color is for example 0 then don't draw pixel at all or if it is not possible (because for example you cannot break pixel shader function) just disable Z buffer for drawn pixel.

However is any solution for fixed function pipeline without using shader?

 

 

However on the other hand I suppose earlier or later I would need functionality of partly transparency so maybe I should go into this direction even if I don't need it now. In this way it would be universal solution for future purposes. So I should determine firstly distance from camera of all alpha-blended objects and based on that the order of drawn is determined from back to top (alpha blended objects are always drawn at the end and moreover the order between them is also set), am I right?

Edited by anders211

Share this post


Link to post
Share on other sites


However on the other hand I suppose earlier or later I would need functionality of partly transparency so maybe I should go into this direction even if I don't need it now. In this way it would be universal solution for future purposes. So I should determine firstly distance from camera of all alpha-blended objects and based on that the order of drawn is determined from back to top (alpha blended objects are always drawn at the end and moreover the order between them is also set), am I right?

 

Yes this looks correct.

Share this post


Link to post
Share on other sites

In D3D9 fixed pipeline there's an alpha-testing stage which you can configure to get the result you want.  For documentation, please read: https://msdn.microsoft.com/en-us/library/windows/desktop/bb172254%28v=vs.85%29.aspx - Google "alpha test" for further information and examples.

In fact I use alpha testing. The problem is that football player is not visible after alpha test. The print screen looks exactly the same as in my first e-mail with exception that there is none football player at all behind the net. OK, I understand. So I have some bug because after alpha test if it doesn't pass Z buffer shouldn't be overwritten for such pixel. I will try to debug why Z buffer is overwritten for the pixel.

Share this post


Link to post
Share on other sites

Unfortunately it doesn't work. Please see at the image. One print screen which presents that whole net overwritten Z buffer. In another picture how my model with vertices looks like in blender.

It seems that in practice alpha testing nevertheless if fail or pass always write to Z buffer. That is why I originally asked if there is any chance with fixed function pipeline to enable Z buffer only for ALPHA CHANNEL > 0 and disable Z buffer for alpha = 0. Because it seems that Z buffer is always overwritten no matter if alpha test pass or not. I am googling and generally opinion is that writing to Z buffer is the last action of processing, alpha test is before, so Z buffer shouldn't be updated. So I don't know what might be wrong in my code. Grass is seen because geometry of grass is written before geometry of net. Football player and other objects are written after the net so they are not visible.

Here is my code:

 d3d::pDev->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);
    d3d::pDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    d3d::pDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    d3d::pDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    d3d::pDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    d3d::pDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    //d3d::pDev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); //if I uncomment it we back to the issue presented in my first post

    //Make sure that Alfa is disabled for net
    D3DCOLORVALUE lackAlfa;
    lackAlfa.r = 0;
    lackAlfa.g = 0;
    lackAlfa.b = 0;
    lackAlfa.a = 0;
    mGoalnet.mat.at(1).Specular = lackAlfa;
    mGoalnet.mat.at(1).Emissive = lackAlfa;
    mGoalnet.mat.at(1).Diffuse = lackAlfa;
    mGoalnet.mat.at(1).Ambient = lackAlfa;

    for(u32 i=1; i<mGoalnet.subsets; ++i) //draw only net without crossbar, without post
    {
        d3d::pDev->SetMaterial(&mGoalnet.mat.at(i));
        d3d::pDev->SetTexture(0, mGoalnet.texture.at(i));
        mGoalnet.mesh->DrawSubset(i);

    }

    d3d::pDev->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
    d3d::pDev->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
    d3d::pDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
Edited by anders211

Share this post


Link to post
Share on other sites

OK I mess up it with D3DRS_ALPHABLENDENABLE. I should use D3DRS_ALPHATESTENABLE instead of  D3DRS_ALPHABLENDENABLE. Thanks.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!