Can you help me with a particular blending?

Started by
13 comments, last by BlueChip 20 years, 1 month ago
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]
Advertisement
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);

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);
<br><br>in this case texture is solid.... <img src="sad.gif" width=15 height=15 align=middle><br>Could help some screenshots? </pre>
two days are passed...
many roads have been covered...
but the solution is not reached...

who will find it?



[edited by - BlueChip on February 23, 2004 9:33:10 AM]
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.
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]
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
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.
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

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.

This topic is closed to new replies.

Advertisement