Archived

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

Can you help me with a particular blending?

This topic is 5037 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 people... I'll try to explain myself... I would have to texture a mesh with a texture, and to use another texture as alpha_blend of the first texture... Mr. Bloom say that for this operation I must set SetTextureStageState in this way
		// stage 0 coloring : get color from texture0*diffuse
		lpDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
		lpDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		lpDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

		// stage 0 alpha : nada
		lpDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
		lpDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);

		// stage 1 coloring : nada
		lpDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
		lpDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_DIFFUSE);

		// stage 1 alpha : get alpha from texture1
		lpDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
		lpDev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  
but this doesn't work..... all is white.... I would want that - where my texture1 is black, texture0 is solid, - where my texture1 is white, texture0 is invisible, - where my texture1 is gray, texture0 is trasparent ( dependently by gray hue), or vice versa... Can you help me? thanks p.s: I've done many tests, but I can't apply alpha from texture stage X to texture stage Y... I can apply alpha to texture stage X only from D3DTA_TFACTOR or D3DTA_DIFFUSE [edited by - BlueChip on February 21, 2004 3:33:15 PM]

Share this post


Link to post
Share on other sites
Stage 1 coloring should be set to COLORARG1, D3DTA_CURRENT. This means pass the current (from stage0) value along as this stage''s color value.

You must also enable alpha blending, and set the blending mode to newcolor*newalpha + oldcolor*(1-newalpha).


lpDev->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
lpDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
lpDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);


You should also finish your stages off with a ''disable'' to ensure a previous effect using stage 2 or higher doesn''t affect this effect.


lpDev->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
lpDev->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

Share this post


Link to post
Share on other sites
Namethatnobodyelsetook thanks for your aid,
but this configuration doesn''t work..
(I''ve already tried it)

m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

// stage 0 alpha : nada
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);

// stage 1 coloring : nada
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);

// stage 1 alpha : get alpha from texture1
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
[code]

in this case texture is solid....
Could help some screenshots?

Share this post


Link to post
Share on other sites
In your new code you''ve changed the alpha to be from CURRENT instead of TEXTURE. It should be TEXTURE.

You must also ensure you have a texture with alpha in it. A 32 bit PNG or TGA is the simplest way, but obviously wastes 24 bits per pixel. Unfortunately most cards don''t actually support an alpha only image format for some reason. Also, loading greyscale images tends to be loaded as grey, not alpha, when using D3DX. Unless you use a 32 bit PNG, TGA, or a DXT3/DXT5 texture you likely don''t have any alpha in your image. You may be able to use a 2 channel grey/alpha image loaded as A8L8. This wastes only 8 bits, which is, unfortunately, the best solution most cards offer.

If you can use the image and alpha in the same texture, rather than needing a seperate alpha texture you''ll be able to save GPU memory, save GPU memory bandwidth for fetching a second texture, save a texture stage enabling support for older cards, and possibly save a clock tick per pixel drawn.

Also, you really should consider using DISABLE in stage 2. You''re just waiting for accidents to happen otherwise.

Share this post


Link to post
Share on other sites
Which effect are you going for exactly.

When you say the second texture is an alpha_blend of the first, do you mean

1. It's just alpha, and you want to blend with the frame buffer, or
2. It's alpha and color that you want to blend with stage0?

The above was for #1, if #2

try this... you don't need alphablendenable in this case.
0, colorop, selectarg1
0, colorarg1, texture
0, alphaop, selectarg1
0, alphaarg1, current

1, colorop, blendtexturealpha
1, colorarg1, texture
1, colorarg2, current
1, alphaop, selectarg1
1, alphaarg1, current

2, colorop, modulate
2, colorarg1, diffuse
2, colorarg1, current
2, alphaop, selectarg1
2, alphaarg1, current

3, colorop, disable
3, alphaop, disable

which does the following.
0 - take first texture
1 - mix texture and previous stage using alpha of this texture
2 - multiply by vertex color or lighting
3 - end


[edited by - namethatnobodyelsetook on February 23, 2004 12:48:41 PM]

Share this post


Link to post
Share on other sites
Hi Namethatnobodyelsetook, thanks for your help.

I''ll try to follow your advice step by step...

1)
quote:

In your new code you''ve changed the alpha to be from CURRENT instead of TEXTURE. It should be TEXTURE


sorry... my error, but also with the change, it doesn''t work.
All is solid.

2)
I''ve an ATI Radeon96000pro and I use BMP format for my texture.
I think that for this point there are not problem... right?

3)
quote:

If you can use the image and alpha in the same texture, rather than needing a seperate alpha texture you''ll be able to save GPU memory, save GPU memory bandwidth for fetching a second texture, save a texture stage enabling support for older cards, and possibly save a clock tick per pixel drawn.


No... unfortunately in this case I can''t use the image and alpha in the same texture.
I must built a SplatTexturing system...

4)
quote:

Which effect are you going for exactly.

When you say the second texture is an alpha_blend of the first, do you mean


I say 1) It''s just alpha, and you want to blend with the frame buffer.
Texture in stage 1 must give to me the value of fade of stage 0 texture.. (sorry for the terrible explanation)

5)
I go to try your setting... and then I''ll come back

Share this post


Link to post
Share on other sites
quote:
Original post by BlueChip
I''ve an ATI Radeon96000pro and I use BMP format for my texture.
I think that for this point there are not problem... right?


BMP does not support alpha... only 24 bit images, not 32 bit. Also, when saving as an 8 bit greyscale, it is loaded as grey, not alpha.

If you can''t use PNG, or don''t have software that allows you to edit the alpha (most people use Photoshop), you''ll have to write some code to work around this limitation...

If you are using photoshop, make a greyscale image. Add an alpha channel to it. Draw your shape in your alpha channel. Save it. D3DX should load it as A8L8 if you card supports it, or A8R8G8B8 otherwise.

If you just make a grey image, D3DX will load it as L8, or X8R8G8B8 by default. If you request D3DX to load it as A8, A8L8, or A8R8G8B8, the alpha will be all 255.

You need to ask D3DX to load the image as A8R8G8B8, or A8L8, and lock surface level 0 of the texture. Then, for each pixel, copy the R, G, B, or L value into the alpha bits. Now, unlock the surface, and ask D3DX to recalculate the mipmaps.

Share this post


Link to post
Share on other sites
Ok.. I''ve tested....
result:

With your setting there is a little forward step.
Now where alpha texture ( texture in stage 1 ) is black the image texture is full visible, where it is white the resul texture is white and where it is gray the result texture is gray.
So where the alpha texture is black all works fine, but where the texture is gray or white, there are not the right fade value.

I get the same results with D3DTOP_LERP, D3DTOP_ADD, D3DTOP_MODULATE...


m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);

// stage 1 coloring : nada
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);

m_pd3dDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pd3dDevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
m_pd3dDevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pd3dDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT);

m_pd3dDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pd3dDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);


- EDIT -
opss... I see now that it doesn''t work with black....
I use D3DXCreateTextureFromFileEx with 0xff000000 as alpha color

Share this post


Link to post
Share on other sites
Your image only has useful alpha when black, because you use a colorkey of 0xff000000. What you want is no colorkey, and using a 32 bit source. Also, you''re now using the code that I said was for option 2 (blending two textures, then writing to framebuffer).

When you have black, your alpha (because of the colorkey) is 0, and you see the first texture. When you don''t have black your alpha is 255, and you see the grey shades in your RGB texture.

To get those grey values interpreted as alpha, you need to lock the texture and move the RGB data to the alpha channel, as I said, or use a format, such as a 32bit PNG, which contains alpha information as well as RGB data. You need an appropriate paint package to draw on alpha channels... most don''t let you create an alpha channel in your image.

Share this post


Link to post
Share on other sites
^________^

ok now ( perhap ) I''ve undestand....
sorry but mother nature has been cruel with me

I must use an 32 bit texture with alpha channel...
PaintShopPro ( I''m using it ) support only RGB format ( so 24 bit) and not ARGB with 32 bit...

So I would have to lock my texture and then to add alpha channel...
ok.

but this give me a problem...
I would want to use this, for my platting system.

A texture ( for exemple a grass texture ) can be used in differents places, and in each place it can to have different alpha, so I would have to lock it and then to add alpha channel every frame, in every splat-chunk.

And I must do it for each texture...

If I don''t mistake if I''ve 1 texture of 512x512 pixels, I must overwrite 262144 byte....
with 4 texture -> 1048576
and if I''ve 5 plat-chunk in my terrain-chunk I''ve I must overwrite 5242880 byte every frame...

Is not heavy?
Who does use splatting, must use this technic?

PS:
Namethatnobodyelsetook I do not want to discuss your advice,
I appreciate a lot your big help, but before of doing something I would want to understand fine the problem.

Thanks again!

BlueChip
the splatting student

Share this post


Link to post
Share on other sites
Yes, you need a texture with alpha. Since you can''t do it in your paint package you need to do it in code. This doesn''t mean you need to modify things per frame though.

GameInit
..Load textures
..Convert textures from L8, or R8G8B8 to an alpha format

GameLoop
..Use textures as you had always intended.

So, it''s just a load time performance issue.

--

How much alpha do you need? Since you never know which cards will support which formats you need to rank each format. You want the lowest number of bits that contain atleast a certain amount of alpha bits.

If you need 8 bits of alpha, you can try A8, A8L8, A8R8G8B8.
If you only need 4 bits, you can try A8, A8L8, A4R4G4B4, A8R8G8B8.
If you only need 1 bit, you can try A8, A8L8, A4R4G4B4, A1R5G5B5, A8R8G8B8.

Once you''ve decided on what you need, you''ll to convert the textures. For simplicity, force D3DX to load as L8 (if you save as greyscale), or X8R8G8B8 (if you save as 24 bit).

You will now need to at runtime/loadtime:
1. Load original image as L8, or X8R8G8B8, and without mipmaps.
2. Determine which wanted mode is support on this hardware
3. Create new texture in supported format from #2.
4. Lock surface level 0 of both loaded and created textures.
5. Copy data from loaded texture into created texture''s alpha bits.
6. Unlock both surfaces.
7. Have D3DX filter the mipmaps for the new texture.

--

Another option is the Direct3D Texture Tool... it comes with the SDK. It can load images, copy data into the alpha channel, and save in a new format. You could use this to make DXT3, DXT5, A8R8G8B8, A8L8, just A8, or whatever.

You may still want to rank formats as above, and ask D3DX to load the texture into the best supported format.

Share this post


Link to post
Share on other sites
ok... I''ve learned at to add alpha-channel into a texture.thanks to your explanations...
the more is done..

now the ultimate point...

I must to see imagetexture in the screen, with a fade linked to alphachannel.
I can''t to copy alphachannel from alphatexture to imagetexture, but I must to use a right blend....

I''ve tried previous configuration, but nothing...
Can you give me help another time?
the last one I hope...

If I do this, I''ve finished my terrain-sub-engine...

bye

Share this post


Link to post
Share on other sites

m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);

m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);

m_pd3dDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pd3dDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);


That should work if you've got the correct values in the alpha channel. Remember that alpha blended objects need to be drawn after non-alpha blended objects, and they need to be drawn furthest objects first, closest objects last.


[edited by - namethatnobodyelsetook on February 25, 2004 3:36:57 PM]

Share this post


Link to post
Share on other sites