Jump to content
  • Advertisement
Sign in to follow this  
sipickles

Multistage Texturing

This topic is 4864 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

Hello! I am trying to produce blended texture effects, without the need for multiple passes. I have referred to articles like the hardcode article on gamedev, 'texture splatting' but its not having it for me! That article describes how to use an alpha map in stage 0, combined with a texture in stage 1, rendered, then repeated in further passes. I am trying to use one base texture (no alpha), with further textures containing alpha data for the other stages. Can anyone demystify this for me? I am in a muddle! :) Here's my code:
		_device->SetTexture(0, _dirt); // no alpha in this texture
		_device->SetTexture(1, _sandy); //this tex has alpha channel
		_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
		_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

		_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE2X);
		_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

		_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
		_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);

		_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
		_device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
		_device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);

		_device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
		_device->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
		_device->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);

		//Enable alpha blending
		_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);


The textures seem to blend but are not influenced by the alpha channel in the stage 1.... Thanks Simon [Edited by - sipickles on July 23, 2005 9:01:59 AM]

Share this post


Link to post
Share on other sites
Advertisement
Just so I'm clear, are you trying to use the alpha channel of the second texture to control how much of each of the two textures is used? i.e. Alpha=0 means 100% of texture0 and 0% of texture1; Alpha=0.5 means 50% of texture0 and 50% of texture1; and Alpha=1 means 0% of texture0 and 100% of texture1.

If so, then I suspect you may be thinking of some part of frame buffer blending and/or the multitexture blending cascade in a slightly wrong way. A quick recap (apologies for parts of this you already know):

1) Frame buffer blending (as controlled by D3DRS_ALPHABLENDENABLE, D3DRS_SRCBLEND, and D3DRS_DESTBLEND) controls the blending between the pixel already in the frame buffer (i.e. rendered previously) and the pixel currently being rendered.


2) The pixel currently being rendered (and so subject to frame buffer blending) is the result of the complete multi-texture blending cascade, i.e. the colour and alpha value of that pixel are determined by what the operation in the last active texture do.


3) Frame buffer blending has no affect on what happens between texture stages in the multitexture blending cascade.


4) Texture stages in the multitexture blending cascade aren't independent, one feeds into the next. Additionally, alpha and colour are totally separate for most operations, one doesn't have any affect on the other.


5) Personally (before I used pixel shaders), I always write out the multitexture cascade as a mathematical expression - for me it makes it easier to see what's going on. Your setup does the following:

temp_colour = (texture0_colour * vertex_colour) * 2
temp_alpha = vertex_alpha
pixel_colour = temp_colour * texture1_colour
pixel_alpha = temp_alpha * texture1_alpha

pixel_colour and pixel_alpha are the only things which make it through to the frame buffer in the above.


6) So your setup samples a colour from your dirt texture and tints it by the vertex colour, then modulates the tinted dirt with the sand texture; independently of the colour, it gets the alpha for stage 0 from the alpha component of the vertex colour (CURRENT==DIFFUSE for stage 0) and modulates that with the alpha channel in the sand texture.


7) The result of the above then goes to the frame buffer blend and does the following:

visible_pixel_colour = (pixel_colour * pixel_alpha) + (framebuffer_colour*(1-pixel_alpha))

i.e. it's just a linear interpolation between the pixel that's being written, and the pixel already in the frame buffer.


8) So the alpha of your sand texture modulated with the alpha of your vertex colour is controlling the transparency of the modulated textures and vertex colours with respect to what's already in the frame buffer; which I suspect is not what you want...


9) What I *think* you're after is a linear interpolation between the sand texture and the dirt texture based on the alpha channel of the sand texture modulated with the alpha channel of the vertex colour.

To achieve that, take a look at what the following blending operations do:

D3DTOP_BLENDCURRENTALPHA, D3DTOP_BLENDTEXTUREALPHA, D3DTOP_BLENDDIFFUSEALPHA

It's likely you'll have to re-arrange the order of your textures. IMO it's easiest done by writing exactly what you require as an expression, and then finding the operators which best fit that expression.


10) It's extremely easy to do that kind of blend with a pixel shader [wink]

Share this post


Link to post
Share on other sites
In order to do multiple texture splats in the texture blending unit, you have to use the TEMP texture stage (make sure your card supports it... all modern ones should) Here's what you want to do:

Stage 0 ( put your solid base texture here )
-----------------
COLOROP: MODULATE
COLORARG1: DIFFUSE
COLORARG2: TEXTURE
ALPHAOP: DISABLE
RESULTARG: TEMP

Stage 1 ( put your first texture splat here.. something like grass )
-----------------
COLOROP: MODULATE
COLORARG1: DIFFUSE
COLORARG2: TEXTURE
ALPHAOP: DISABLE
RESULTARG: CURRENT

Stage 2 ( put your first alphamap here, eg grassalpha )
-----------------
COLOROP: BLENDTEXTUREALPHA
COLORARG1: CURRENT
COLORARG2: TEMP
ALPHAOP: SELECTARG1
ALPHAARG1: TEXTURE
RESULTARG: TEMP

Stage 3 ( put your 2nd texture splat here... say, snow )
-----------------
COLOROP: MODULATE
COLORARG1: DIFFUSE
COLORARG2: TEXTURE
ALPHAOP: DISABLE
RESULTARG: CURRENT

Stage 4 ( put your 2nd texture splat alpha here... snowalpha )
-----------------
COLOROP: BLENDTEXTUREALPHA
COLORARG1: CURRENT
COLORARG2: TEMP
ALPHAOP: SELECTARG1
ALPHAARG1: TEXTURE
RESULTARG: CURRENT

And there you have it. A base texture and two texture splats will be rendered. If you want, you can add a 3rd splat in there by changing stage 4's result arg to TEMP and then repeating the splatting stages again for stage 5 and 6 (just make sure the final resultarg is current so it all gets shown to the screen). Most cards have a maximum of 8 texture stages, so keep that in mind.

Hope that helps! I know I had the same problem for a while until I figured out the TEMP stage :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!