PDA

View Full Version : Direct3D and Alpha Masks, impossible?



TheLion
02-08-2003, 03:14 PM
I was playing around with Direct3D for 2D purposes and I was kinda hoping to be able to use a bitmap that contains the full image and another image (black and white maybe grey) for the mask and transparency. I think that technique is called Masking, but I can't find any tutorials that use it with Direct3D.

Can anyone tell me how to something like this?

Traveler
03-08-2003, 12:50 PM
Have you tried using TGA files? I use it for opengl stuff, but I'm quite sure you can also use it for direct3d.

Clootie
03-08-2003, 08:22 PM
Basically there are two methods to do this: color keying and alpha masks. Color keying basically defines some color (black for example) as transparent, so rendering color-keyed picture means all black pixels are transparent (masked out?). Alpha mask suppose usage of additional layer in picture (called alpha or transparency layer) that defines how much of backround image is composed with your new image.
From your description (mentioning *grey* color) I assume you want alpha masking. For this you should 1) store your image in files supporting alpha layer - tga, dds allows this (some other formats allows this too); 2) enable alpha blending then rendering your data

[background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000] // Set up the textures
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_TEXTURE);
m_pd3dDevice.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

m_pd3dDevice.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

// Set initial alpha-blending mode
m_pd3dDevice.SetRenderState(D3DRS_ALPHABLENDENABLE , iTrue);
m_pd3dDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pd3dDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

TheLion
04-08-2003, 06:49 AM
Thanks for the replies, but they don't explain what I'm really looking for (they might be usefull nevertheless), so I wasn't really clear when I explained what I was looking for ! :)

Okay... what I actually meant was the old version of this trick to do this... In OpenGL (and Windows Canvas) there is the ability to read the alpha mask from a seperate file then when you apply the texture you first draw the mask (with some special settings mostly) and then you draw the image you actually want to draw over the mask, which would resolve in an image with either tranparency and in some cases even blending (50% transparency and stuff).

Would that be possible in Direct3D (9) or does DirectX only supports the use of an alpha-channel/layer?

See it like making an image transparent by using something like multitexturing with a mask-file (a black and white bitmap) and an actual image file (multicolour).

Clootie
04-08-2003, 09:42 AM
In any case you should get your "mask" image in alpha layer. For "mask" (not alpha-blending) this can be easily done by this (assuming transparent color in your mask is black):
[background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000]D3DXCreateTextureFromFileEx(Device, 'mask_file.bmp', D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, {*}$FF000000{*black*}, nil, nil, OutMaskTexture);


Later you can setup multitexture pipeline like this:
[background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000] m_pd3dDevice.SetTexture(0, RealImageTexture);
m_pd3dDevice.SetTexture(1, OutMaskTexture);


// Set up the textures
m_pd3dDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
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_TEXTURE);
m_pd3dDevice.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

m_pd3dDevice.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);

m_pd3dDevice.SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pd3dDevice.SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

// Set initial alpha-blending mode
m_pd3dDevice.SetRenderState(D3DRS_ALPHABLENDENABLE , iTrue);
m_pd3dDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pd3dDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

Avatar
04-08-2003, 10:43 AM
Hmmm

Wouldn't it be more safe to Select the 2nd texture as Alpha argument instead of modulating it with the 1st level.

I mean, you don't define what is the first alpha argument on the first level ... So, if he didn't "reset" the Texture stage states of an other effect(which implies another alpha argument) then it could change the value of alpha, couldn't it ?


m_pd3dDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
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_TEXTURE);

m_pd3dDevice.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);


This is how I would do ... Maybe I'm wrong :) lol

Bye
Avatar

ps : By the way, didn't you made a mistake writing COLORARG instead of ALPHAARG ?

Clootie
04-08-2003, 12:43 PM
>Wouldn't it be more safe to Select the 2nd texture as Alpha argument instead of modulating it with the 1st level.
Probable, I've assumed what original texture do not have alpha layer (as TheLion do not want to use it :-( ), so by definition alpha=1 (opaque).

So settings for "1" stage can be:
[background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000]
m_pd3dDevice.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
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_TEXTURE);
m_pd3dDevice.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);

I prefer to set all arguments for texture stage, so some bad driver will not be confused by possible strange combination of states.

>ps : By the way, didn't you made a mistake writing COLORARG instead of ALPHAARG ?
Yep, I've corrected this.

wagenheimer
28-08-2012, 12:04 AM
Is it possible to do this without using Multitexturing??

I have these two images :
Texture and Mask.

I want to blend the two and get an transparent texture! Is it possible?

LP
28-08-2012, 01:44 AM
You could do this in shader, but it will still require binding two textures simultaneously, or putting both images on the same texture and adjusting texture coordinates. Why can't you integrate the mask as an alpha-channel in the same image?

wagenheimer
28-08-2012, 01:51 AM
Why can't you integrate the mask as an alpha-channel in the same image?

Because this image comes from a Running Video! =)... I need to use the video with Transparent Alpha. On original video file, on the left side of the video I have the colored image, and on the right side I have the mask! I think it is not possible to have ogg videos with alpha-channel on it, but somehow this game does the trick using these kind of masks!

I'm sure this is possible of doing without using shaders, because I got this video from a game which does not use shaders. But I'm trying to figure out how it's done!

LP
28-08-2012, 02:57 AM
I'm sure this is possible of doing without using shaders, because I got this video from a game which does not use shaders. But I'm trying to figure out how it's done!
Other than multitexturing, the other approach I can think of, is rendering first image on the render target (which has alpha-channel) without affecting alpha, then rendering the second image affecting only alpha channel. Then, the resulting render target is drawn on the screen,