Stumped on Terrain Texture Blending (screenshots)

Started by
10 comments, last by Kibble 19 years, 8 months ago
I have put together a terrain engine where each quad can have its own texture. Where I am stuck is how to get these textures to blend together. I can't seem to find a tuturial that shows how to do it. Can anyone help me out or point me to a resource that shows how to do this? Basically, I want to take this: And turn it into this: Each of my vertices contains this info (C#):

public struct MyVertex
{
	public float X, Y, Z;	
	public Vector3 Normal;
	public float Tu1, Tv1;
	public float Tu2, Tv2;
}



Thanks! [Edited by - strahan on August 20, 2004 3:46:04 PM]
Advertisement
Hi strahan:

I'm not the most experienced to talk, but in my vision as player I've to say that normally textures aren't merged by the software (As far As I Know...). In many simulators I've played with there is a transition texture that is used to merge the two parts (i.e green to mud).

Just trying to help!

Bye! :)
?J@cob=========================Computer Science Studentjacobmendozap@hotmail.com
I'm sorry I can't help you, but I'd like to know how you apply several textures for different faces? :)

regards
There is a technique described on the tutorial Terrain Texture Generation in which you generate the texture blends based on the height of each vertex, its probably not quite what you are looking for, but close, it may give you some ideas.
ok man, you're half way there. next step, take an alpha map and map each pixel to each quad in your landscape. you'll need a map for each texture you'll want to blend.

as you draw each texture you'll look up the appropriately mapped alpha value and do a blend.
to calculate the amount a given texture weights on the quad, look at each adjacent texture and calculate a weighting system.

in most cases you'll need to multipass if you have several textures and want to support legacy hardware.


just google charles bloom texture splatting for a better explanation.
"Let Us Now Try Liberty"-- Frederick Bastiat

Dreddnafious Maelstrom-

How do I create this Alpha Map? Is there a tool that does this?

Also, I don't understand how the grass for example would carry over partially into another quad or the dirt would carry over partially into the grass quad (see screenshots).

Do both the grass and dirt textures get assigned to the same quad?


FoxHunter2 - To map a texture to each quad I simply set the TU and TV coordinates to 0,0 at the upper-left, and 1,1 at the lower right coordinates of the quad.

Kwizatz- I have seen this article but unfortunately it does not do what I want. I want the user to be able to paint the terrain regardless of the height of the terrain.

Thanks everyone.
How complicated are you willing to get and what target audience do you want? If you use a pixel shader, this is pretty easy. You can send 4 textures in, one for grass, one for rocks, one for snow, then a fourth texture who's green value contains the transparency of the grass, who's red value contains the transparency for the rock and who's blue value contains the transparency for the snow. All three values (red, blue, green) add up to 1.0. So you may get 10% snow, 50% rock, and 40% grass for instance. Then combining these in the pixel shader to calculate the final pixel color is super easy.

The fourth texture would be created at run-time and be based on the terrain's height. You would take each quad of the terrain, then create a linear transparency texture for the quad. This means that you would calculate the transparency for each terrain texture (rock, grass, snow) at some terrain height. For instance, you'd set the transparency texture's top left and bottom left blue value(snow) corresponding to how high the terrain point is. If it's at some maximum point, the blue value gets 1.0, and red and green are set to 0. If it's mid-way up to the max height value, you set the blue value to 0, because there's no snow half way down the mountain, and set the red value (rocks) to 15% and the green value (grass) to 85%.

These values are specified at design time in a lookup table. Grass will be 100% prevalent at ground height 0 and will fade out to 0 at 3/4 of the max height. Rocks will be 0 at 1/2 max height, 100% at 3/4 max height, and 0 at 15/16 max height. Snow will be 0 at 3/4 max height and 100% at max height. I hope that makes some sense.

Anyway, you find the transparency of each point in the quad, then linearly interpolate between them to create the rest of the texture.

Chris
Chris ByersMicrosoft DirectX MVP - 2005
Check out this tutorial on terrain texture splatting. I believe you will find it exactly what you are looking for.
Take a look at the texture ops D3DTOP_LERP, D3DTOP_BLENDDIFFUSEALPHA, D3DTOP_BLENDTEXTUREALPHA, and D3DTOP_BLENDCURRENTALPHA. For example, to do what you want for two textures A and B in D3D8:

Device->SetTexture(0, TextureA);Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);Device->SetTexture(1, TextureB);Device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); // lerp between TextureA and TextureB based on the alpha in the vertexDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);Device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);


Its a bit trickier for more than 2 textures. I've only managed to get 3 textures in one pass (with slightly wrong blending, but looks fine), and if there are more than 3 layers, I have only figured out how to do one layer per pass * n textures.

A pixel shader would be easiest to do this, I'm trying to avoid them for lower end hardware, but you may want to use them. The equation you would basically be looking for to do this in a pixel shader would be:
Texture1 * Weight1 + Texture2 * Weight2 + Texture3 * Weight3 + Texture4 * (1 - (weight1 + weight2 + weight3))
OK. I am trying to get D3DTOP_BLENDDIFFUSEALPHA to work first but so far I just see the texture rendered as normal on the quads (no fading in or out):

device.SetTexture(0, _Texture1);device.SetTextureStageStat(0,TextureStageStates.ColorOperation, (int) TextureOperation.BlendDiffuseAlpha);device.SetTextureStageStat(0,TextureStageStates.ColorArgument1, (int) TextureArgument.TextureColor );device.DrawPrimitives( PrimitiveType.TriangleList, 0, offset/3 );


My question is what values do I set for the diffuse color of the vertices.

That is, what colors make the texture stand out more and what colors make it fade more?

I noticed this value is a Int32 value, not a float so I can't set it to like 0.4.

Thanks!

This topic is closed to new replies.

Advertisement