Mixing two textures in DirectX

Started by
9 comments, last by realguy 14 years, 10 months ago
After spending hours staring at the MSDN documentation on blending in DirectX, I've decided to ask this question on the GameDev forums. I have a game with green dinosaurs. When you shoot a dinosaur, I want it to turn blue, and then fade back into green. I have a green dinosaur texture and a blue dinosaur texture. So my question is, is there a way to fade from one texture to the other? Let me know if you need clarification about this. Thanks so much to anyone who can help me.
Advertisement
Either set a vertex shader constant that's the fade amount (from 0 to 1) and pass it to the fragment shader, or just set it as a fragment shader constant.

Then sample both textures and lerp() between the two colors based on the value you sent in.

To avoid always sampling both textures you could make the fading version of the shader a separate technique.
Thanks for the really quick reply, RDragon. I'm a DirectX noob so I didn't quite catch all of that, but it sounds like I need to learn about vertex shaders, and maybe I can stop trying to understand alpha blending. Thanks for giving me something to go off of. Hopefully I can figure it out from here.
Are you using 2D? I had a similar problem and solved it by drawing the blue dinosaur over the green one. I changed the alpha value of my blue dinosaur over a time of, let's say one second from 0 to 1 and than back again to 0. But this is actually not a "mixing" of textures. But you have some kind of flashing which was good enough for my application.
realguy, you need to learn either pixel shaders or texture stage states (shaders are the better way to go -- they're more flexibly and IMO clearer and easier). I'm assuming you're using D3D9.

For shaders, use 'lerp', as RDragon1 said. For texture stages use the D3DTOP_BLENDFACTORALPHA op.
Thank you, ET3D. I'll take a look at doing it with with texture stage states, because I'm more familiar with that. Sounds like I need to learn pixel shaders though. Thanks everybody for your input. This is 3D, snowprog, but drawing the second texture with a given alpha value over the first one is basically what I'm trying to achieve.
You don't need shaders for that. It may be a good idea to look into shaders sooner or later though.

Draw the first texture normally, then setup this for the second:

SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );SetTextureStageState( D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );SetTextureStageState( D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );SetTextureStageState( D3DTSS_COLOROP, D3DTOP_DISABLE, 1 );SetTextureStageState( D3DTSS_ALPHAOP, D3DTOP_DISABLE, 1 );SetTextureStageState( D3DTSS_COLOROP, D3DTOP_MODULATE );SetTextureStageState( D3DTSS_COLORARG1, D3DTA_DIFFUSE );SetTextureStageState( D3DTSS_COLORARG2, D3DTA_TEXTURE );SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );


...and use 0x00ffffff + ( iAlphaValue << 24 ) );

as your vertex color value where iAlphaValue goes from 0 (fully transparent) to 255 (fully opaque)

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Hmm... That code looks very useful, but I don't like the idea of changing the color on all the vertices. I was trying to do this:

device->SetRenderState(D3DRS_TEXTUREFACTOR, 0x44ffffff);
device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_BLENDFACTORALPHA);

But it doesn't seem to do anything. If you could explain why the above code doesn't work, that would be great. In the meantime, I'll be looking up shaders. Thanks.
You could also use the material alpha, so you don't have to modify the vertex diffuse color.

How have you done your setup for rendering this?

Do you want to render both textures at the same time? (two texture stages?)

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Yes, I'm trying to do it with 2 texture stages. This is how I was doing it:

device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

// Supposed to make the dinosaur partly blue.
device->SetRenderState(D3DRS_TEXTUREFACTOR, 0x44ffffff);
device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_BLENDFACTORALPHA);

device->SetTexture(1, blueTex);
device->SetTexture(0, greenTex);
// Draw dinosaur here.

But the blue texture is not showing up.

I'm going to try to do this in HLSL, but if there is a way to make it work like this, that would be great.

This topic is closed to new replies.

Advertisement