• Advertisement
Sign in to follow this  

Help with per-vertex alpha blending

This topic is 4791 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've been banging my head against this one for too long and it's driving me nuts. The essence of my problem is just how to get alpha blending to work. In its most simple form, I want to blend between two textures based on per-vertex weights. I started by trying to modify existing multitexture programs, but to no avail. This is to blend between two landscape types. For example, given a triangle with corners A,B,C let's say: A.diffuse = D3DCOLOR_RGBA(255,255,255,255) (1.0f - grass) B.diffuse = D3DCOLOR_RGBA(128,128,128,128) (0.5f - blend grass/dirt) C.diffuse = D3DCOLOR_RGBA(0,0,0,0) (0.0f - dirt) struct s_Vertex { float x, y, z; D3DCOLOR dwDiffuse; D3DCOLOR dwSpecular; float tu1, tv1; float tu2, tv2; }; #define VERTEX_FVF=(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX2) I define all the vertices, and in the Render() step: if( SUCCEEDED(g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE)) ) { g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); } ... // base layer = base texture g_pd3dDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0); g_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1); g_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE); // ???? Maybe want this to be diffuse color, which will blend away // ???? according to diffuse corner weights?? g_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); g_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); ... // second layer = competing texture "poking through" // ???? THIS IS WHERE I BREAK DOWN g_pd3dDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1); g_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_????); g_pd3dDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); g_pd3dDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_CURRENT); // I assume the SRC_BLEND and DEST_BLEND will use DIFFUSE and 1-DIFFUSE? g_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); g_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); I can get one or the other to render with a faded corner and overwrite one another in stage 0 or 1, but I'm at a loss for the appropriate colorop/alphaop for stage 1. HELP!!!

Share this post


Link to post
Share on other sites
Advertisement
Odds are you want the second method, but I'll explain both.

If you want to do multi-pass blending you draw twice, with alphablend enabled on the second pass, like this:

stage 0: texcoord 0, colorop = arg1, colorarg1 = texture, alpha = anything.
draw

stage 0: texcoord 1, colorop = arg1, colorarg1 = texture, alphaop = arg1, alphaarg1 = diffuse, alphablendenable = true, srcblend = srcalpha, destblend = invsrcalpha.
draw again


This will be slow, but it will work. Or you can use multitexturing and no alphablending.

same as what you have except
alphablendenable = false;
stage 1: colorop = blendiffusealpha

Blending inside texture stages doesn't need alphablend to be enabled. Just the framebuffer blend uses that.

Share this post


Link to post
Share on other sites
Thank You! After switching to my wife's laptop (with a better 3d card, sadly), I got the example to work with the faster method.

When I ran the first program on my PC, it rendered a nice, perfectly white square for me. Soo... I had to resort to the slower method to get the same results.

But both worked beautifully.

Share this post


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

  • Advertisement