Jump to content
  • Advertisement
Sign in to follow this  
kosmon_x

Per-vertex alpha blending

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

Is it possible to blend 2 textures together on the same quad in one pass using per-vertex alpha blending with the fixed function pipeline? I can do it easy enough in two passes, just by swapping SRC/DEST blends. It looks something like this:
// I have 4 verts with a diffuse component. 2 of the verts have 0 alpha for diffuse, 2 of them have 255 alpha for the diffuse.

                pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
		pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
		pd3dDevice->SetTexture( 0, m_Texture1 );
		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

		// pass 2
		pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA );
		pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA );
		pd3dDevice->SetTexture( 0, m_Texture2 );
		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );




But, can it be done in one pass? Thanks :) [Edited by - kosmon_x on June 17, 2005 9:49:49 PM]

Share this post


Link to post
Share on other sites
Advertisement
Why not render the first opaque, then the second with it's transparency?

You can combine two textures with texture stage states and render one quad in one draw call combining both textures. But I don't know how you would go about doing it with vertex alpha, or why you would want to use vertex alpha?

Share this post


Link to post
Share on other sites
Well, I'm trying to nail something down for some terrain. Ideally, I'd want to be able to render 3 textures to one quad (in 2 passes). However, I'm not sure how I'd do this with one diffuse component per vertex.. I'd probably have to change it for the 2nd pass.

How does everyone else do this with the fixed function pipeline?

Share this post


Link to post
Share on other sites
Using texture stage states
stage, colorop, colorarg1, colorarg2
0, top_selectarg1, ta_texture, ta_diffuse
1, top_blenddiffusealpha, ta_texture, ta_current
2, top_modulate, ta_diffuse, ta_current
3, top_disable

What this does is:
stage 0, first texture 100%
stage 1, mix between texture and stage 0 by diffuse alpha
stage 2, multiply stage 1 by lighting or vertex color
stage 3, end

you'll likely also want

d3drs_colorvertexenable, true
d3drs_diffusematerialsource, d3dmcs_color1

which informs D3D to use vertex rather than material colors.

Share this post


Link to post
Share on other sites
Most people use an alpha map. But I think it elludes them that the alpha map usually costs more memory than giving each layer it's own vertex buffer.

I just render a vertex colored non-textured layer of terrain over the whole map first. The colors are based on mip level 1x1 from the mixed terrain textures. Then each layer is rendered with a seperate draw call with it's own buffer. So each layer has it's own vertex value. Having them equal to one will not make them completely opaque, though. Which is what the base color layer is for.

You can see some bad examples of my terrain engine here or here. There's not much blending going on. Sorry, I'm a bit tied between engine changes or I would wip up a better example.

edit: Ah, I dug up a better example here.

Share this post


Link to post
Share on other sites
Hmmm sounds like an interesting approach.. How many layers are being rendered in the screenshots you posted? And is it using shaders or the FFP?

Share this post


Link to post
Share on other sites
In my engine, it's using a vertex shader. But the only reason it uses one is to reduce the size of a vertex. There's no need to store texture coordinates in these vertices. So they only consist of a vector and color, and end up only 16 bytes. Other than that, the fixed pipeline could easily dish it out.

As for the number of layers, there's no limit. In my screen shots, what you see is what you get. If you see three textures, it's three layers. I limited the maximum to 32 layers for the sake of simplifying my editor, but as far as I know, there's no other real reason to do so.

Share this post


Link to post
Share on other sites
Quote:
Original post by Jiia
In my engine, it's using a vertex shader. But the only reason it uses one is to reduce the size of a vertex. There's no need to store texture coordinates in these vertices. So they only consist of a vector and color, and end up only 16 bytes. Other than that, the fixed pipeline could easily dish it out.

As for the number of layers, there's no limit. In my screen shots, what you see is what you get. If you see three textures, it's three layers. I limited the maximum to 32 layers for the sake of simplifying my editor, but as far as I know, there's no other real reason to do so.


Ooh ok... So let me get your technique right: You have a set of 4 vertices for each layer of each quad on the terrain, in addition to one base layer of vertices. So, if one quad has 3 textures blended over it, that quad will essentially be represented by 12 vertices (a set of 4 for each texture), and it will be rendered by 3 draw calls (using a vertex buffer for each layer). (And before all that happens, the base layer of colored verts is rendered). Is that right?

Thanks for all the help... definite rating+++ :)


P.S.: How did you make those light rays? They look great :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Namethatnobodyelsetook
Using texture stage states
stage, colorop, colorarg1, colorarg2
0, top_selectarg1, ta_texture, ta_diffuse
1, top_blenddiffusealpha, ta_texture, ta_current
2, top_modulate, ta_diffuse, ta_current
3, top_disable

What this does is:
stage 0, first texture 100%
stage 1, mix between texture and stage 0 by diffuse alpha
stage 2, multiply stage 1 by lighting or vertex color
stage 3, end

you'll likely also want

d3drs_colorvertexenable, true
d3drs_diffusematerialsource, d3dmcs_color1

which informs D3D to use vertex rather than material colors.


Thank you! This works perfectly :) One question: why do you need "stage 2, multiply stage 1 by lighting or vertex color" and setting the d3drs_colorvertex to true? It seems to work without them.. just curious.

Share this post


Link to post
Share on other sites
If lighting is disabled, stage 2 it will multiply by the vertex color. Try disabling lighting, and changing your vertex color to some extreme color like bright red. Everything should render bright red. Now disable stage 2, and it should remain a blend of textures but without being tinted by your vertex color.

If lighting is enabled, stage 2 will take into account lighting from the fixed pipeline lights. If you disable stage 2 you'll get blended textures but absolutely no effect from lights. The value of lighting goes into D3DTA_DIFFUSE. Try changing the light's color to make the effects of including this stage more obvious.

If you have lighting enabled with a full white ambient, or lighting disabled with white vertex diffuse, then you won't see any effect if you enable or disable stage 2.

COLORVERTEX, TRUE, and DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 are likely defaults. It's best not to rely on defaults as some drivers don't default everything correctly. Also, if one effect changes these settings, you'll need to set them back. It's best to set everything you need.

If COLORVERTEX is false, D3D's fixed pipeline lighting uses material colors.

If COLORVERTEX is true, D3D's fixed pipeline lighting may use material or vertex colors. DIFFUSEMATERIALSOURCE, SPECULARMATERIALSOURCE, EMISSIVEMATERIALSOURCE, and AMBIENTMATERIALSOURCE are used to choose where the lighting system should look for values. Your choices are MATERIAL, COLOR1, and COLOR2. MATERIAL will choose the matching part of a D3DMATERIAL9 that you've SetMaterial()'d into the device. COLOR1 will choose vertex diffuse color. COLOR2 will choose vertex specular color.

Since you require vertex diffuse alpha for your blending, I included the settings that would ensure you're getting diffuse color from the vertex diffuse.

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!