Archived

This topic is now archived and is closed to further replies.

Dov Sherman

Alpha Blending with Transformed Textures

Recommended Posts

I''m working with simple 2D rectangular textures rendered with DrawPrimitive() as a TRIANGLESTRIP. My vertices are D3DFVF_XYZRHW | D3DFVF_TEX1 so I''m working with transformed, lit vertices. What I''d like to do render the texture with all alpha values scaled by a dynamic factor so that I can animate a fading effect for my sprite. How can I do this without needing to directly modify the pixels of the texture itself?

Share this post


Link to post
Share on other sites
Assuming you want to make the sprite more and more transparent so that what is behind it shows through (fading to black is simpler):


METHOD A:

a) Put a diffuse colour (D3DFVF_DIFFUSE) in your vertex format

b) Set your texture stage states so that the alpha channel is selected from D3DTA_DIFFUSE

c) Enable alpha blending and set SRCALPHA:INVSRCALPHA as the blending mode (with alpha test disabled)

d) When you need to fade, lock the vertex buffer and modify alpha part of the diffuse value of each vertex to change the fade level (0-255). Unlock when modifications are finished.

e) Render

Advantages: works on just about all hardware
Disadvantages: you need to mess about locking the vertex buffer (though if its for a sprite, you probably do that to set the position anyway).



METHOD B:

a) Set your texture stage states so that the alpha channel is selected from D3DTA_TFACTOR

b) Enable alpha blending and set SRCALPHA:INVSRCALPHA as the blending mode (with alpha test disabled)

c) When you need to fade, set the fade level (0-255) in the alpha part of the DWORD passed when setting the D3DRS_TEXTUREFACTOR renderstate

d) Render

Advantages: Simple to implement
Disadvantages: Some drivers on older graphics cards get TFACTOR wrong (driver bugs on outdated cards which will never be fixed) and only let you set the TFACTOR once per frame (if at all...)


METHOD C:

a) Set up a vertex shader which moves the fade level from a constant register into oD0.a and process/passes on the vertices as required (the vertex format shouldn''t need a diffuse colour)

b) Set your texture stage states so that the alpha channel is selected from D3DTA_DIFFUSE

c) Enable alpha blending and set SRCALPHA:INVSRCALPHA as the blending mode (with alpha test disabled)

d) When you need to fade, set the vertex shader constant you used in the shader to the fade level (0-1).

e) Render

Advantages: The new way of doing things & simple
Disadvantages: If you don''t have hardware shader support you''ll have to drop to software processing.


All of the above should be roughly the same speed - method A may be a tad slower if your locking isn''t appropriate (location, flags, memory access type). All of them rely on the fixed function pixel processing to do the work using alpha blending, the only difference is how the alpha value makes its way down the pipeline.
You could do some other interesting things if you delved into the world of pixel shaders too.


--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
I use something like the first method... the D3DTSS_ALPHAx stuff is set to D3DTA_DIFFUSE / D3DTOP_MODULATE / D3DTA_TEXTURE, and I modify the alpha value in each vertex to set the opacity.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

Share this post


Link to post
Share on other sites