fixed pipeline texture blending

Started by
10 comments, last by therealremi 16 years, 8 months ago
Is it possible with DirectX fixed pipeline multitexturing to get this effect: texture A is blended with texture B using monochrome single channel texture C as a mask? All textures have different mapping sets. I couldn't find any piece of code that does the above. I saw a solution that assumes texture C is an alpha channel of texture B but this is not the way to go.
Advertisement
Quote:Original post by therealremi
Is it possible with DirectX fixed pipeline multitexturing to get this effect:
texture A is blended with texture B using monochrome single channel texture C as a mask?
All textures have different mapping sets.
I couldn't find any piece of code that does the above. I saw a solution that assumes texture C is an alpha channel of texture B but this is not the way to go.

I don't think so, but I could be wrong. The only way I can think of is to use render to texture to blend the monochrome texture and Texture A, then render to another texture to blend the monochrom texture with Texture B (Using inverse blending), then to render those two textures to the render target.

Which is less than efficient [smile]

Assuming I'm right, and it's not possible, is there a reason you can't update one of the first textures to write the monochrome texture into the alpha channel, and then blend them normally?
Quote:Original post by Evil Steve
Assuming I'm right, and it's not possible, is there a reason you can't update one of the first textures to write the monochrome texture into the alpha channel, and then blend them normally?


This is not possible cause the monochrome texture that is meant to be a mask will be applied with different UV coordinates and has different resolution than the textures that will be blended together.
I know that this would be a trivial task when using pixel shader but for some reasons I try to achieve this effect using texture stages.
Texture[0]=(textureA);Texture[1]=(textureB);Texture[2]=(textureC);ColorOp[0]=SELECTARG1;ColorArg1[0]=TEXTURE;AlphaOp[0]=SELECTARG1;AlphaArg1[0]=CURRENT;ResultArg[0]=TEMP;ColorOp[1]=SELECTARG1;ColorArg1[1]=TEXTURE;AlphaOp[1]=SELECTARG1;AlphaArg1[1]=CURRENT;ColorOp[2]=BLENDTEXTUREALPHA;ColorArg1[2]=CURRENT;ColorArg2[2]=TEMP;AlphaOp[2]=SELECTARG1;AlphaArg1[2]=TEXTURE;ColorOp[3]=DISABLE;AlphaOp[3]=DISABLE;

The first problem with this approach is that it makes use of the TEMP register, which is something that needs to be checked through the D3DPMISCCAPS_TSSARGTEMP device cap. Second is that it messes up your result argument state for the first texture stage. That's something that usually isn't touched and I assume wouldn't be reset back to CURRENT in any of your other shaders. So you might need a quick code "hack" that resets it after the draw call.
Quote:Original post by Zipster
The first problem with this approach is that it makes use of the TEMP register, which is something that needs to be checked through the D3DPMISCCAPS_TSSARGTEMP device cap. Second is that it messes up your result argument state for the first texture stage. That's something that usually isn't touched and I assume wouldn't be reset back to CURRENT in any of your other shaders. So you might need a quick code "hack" that resets it after the draw call.
Ahh, I totally forgot about the temp register, I couldn't think of any way to get the colour into the alpha channel [smile]
Many thanks Zipster. I haven't checked your code yet but I bet it is doing what I want.
The bad news is that I can't set D3DTSS_RESULTARG in the API I'm using (I don't have direct acess to DirectX functions). I can only call:
virtual bool SetTextureColorOp (DWORD stage, DWORD colorOp)=0
virtual bool SetTextureColorArg (DWORD stage, DWORD argNum, DWORD colorArg)=0
virtual bool SetTextureAlphaOp (DWORD stage, DWORD alphaArg)=0
virtual bool SetTextureAlphaArg (DWORD stage, DWORD argNum, DWORD alphaArg)=0

:(
Quote:Original post by therealremi
The bad news is that I can't set D3DTSS_RESULTARG in the API I'm using (I don't have direct acess to DirectX functions). I can only call:
virtual bool SetTextureColorOp (DWORD stage, DWORD colorOp)=0
virtual bool SetTextureColorArg (DWORD stage, DWORD argNum, DWORD colorArg)=0
virtual bool SetTextureAlphaOp (DWORD stage, DWORD alphaArg)=0
virtual bool SetTextureAlphaArg (DWORD stage, DWORD argNum, DWORD alphaArg)=0

:(

Well, shoot :/

I've done some thinking and luckily it may still be possible:
Texture[0]=(textureA);Texture[1]=(textureC);Texture[2]=(textureB);Constant=0x00000000;ColorOp[0]=SELECTARG1;ColorArg1[0]=TEXTURE;AlphaOp[0]=SELECTARG1;AlphaArg1[0]=CURRENT;ColorOp[1]=BLENDTEXTUREALPHA;ColorArg1[1]=CURRENT;ColorArg2[1]=CONSTANT;AlphaOp[1]=SELECTARG1;AlphaArg1[1]=TEXTURE;ColorOp[2]=MODULATEINVALPHA_ADDCOLOR;ColorArg1[2]=CURRENT;ColorArg2[2]=TEXTURE;AlphaOp[2]=SELECTARG1;AlphaArg1[2]=CURRENT;

Quote:Original post by therealremi
I couldn't find any piece of code that does the above. I saw a solution that assumes texture C is an alpha channel of texture B but this is not the way to go.

I'm assuming A and B are colour only without alpha, and C is alpha, and that the resulting alpha in the last stage doesn't matter, because no alpha blending (or testing) is done on the result.

The mentioned solution is presumably:
0. Select Texture A colour
1. Blend Current and Texture B using Texture B alpha

Then you could do something similar just carrying things between stages:
0. Select Texture A colour
1. Select Current colour and Texture C alpha
2. Blend Current and Texture B using Current alpha
Thanks all. I know nothing whatever about DirectX but I managed to tweak Zipster's code to get what I want ;-)
The key hack for me was to use a format for C (the mask) which contains alpha only - fortunately DirectX supports such format. Because evidently you can't use RGB intensity as an alpha information in DirectX texture stages.

This topic is closed to new replies.

Advertisement