Help with per-vertex alpha blending
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!!!
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.
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.
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement