Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

How would I accomplish multi-textured terrain? I need to know how to write the HLSL shader for it. The world already UV maps itself and I can get it to do 1 texture at a time. But I want more than 1 texture being displayed on my screen.

Here is my vertex declaration.

D3DVERTEXELEMENT9 Decl[] =
    {
        {
            0,
            0,
            D3DDECLTYPE_FLOAT3,
            D3DDECLMETHOD_DEFAULT,
            D3DDECLUSAGE_POSITION,
            0
        },
        {
            0,
            0,
            D3DDECLTYPE_FLOAT3,
            D3DDECLMETHOD_DEFAULT,
            D3DDECLUSAGE_TEXCOORD,
            0
        },
        {
            0,
            0,
            D3DDECLTYPE_FLOAT3,
            D3DDECLMETHOD_DEFAULT,
            D3DDECLUSAGE_TEXCOORD,
            1
        },
        D3DDECL_END()
    };

I am also using D3DFVF_XYZ and D3DFVF_TEX2

My variables for for each vertex are X, Y, Z, U1, V1, W1, U2, V2, W2

share|improve this question
    
Have a look at texture splatting. While normally used for texture blending, you can easily adapt it for sharp texture transition over large areas, with low res alpha maps. –  Darcara Aug 20 '12 at 19:42
    
problem is that my lands size is so big that its 128000x128000.. i cant store an image that big –  dvds414 Aug 20 '12 at 20:00
    
With that size you'll probably need to chunk anyway, so one image per chunk might be an option. Or if you want really large areas a 4kx4k 1 channel alpha texture could do, although that might look shitty. –  Darcara Aug 20 '12 at 20:13
    
I managed to load the whole world up without chunking. I made my self a whole engine from scratch so it can do a lot. –  dvds414 Aug 20 '12 at 21:29

1 Answer 1

up vote 2 down vote accepted

In principle multitexturing is as simple as performing multiple texture fetches in the pixel shader and then blending the two colors together using some formula (average, min, max, etc).

For greatest control you can use multiple UV coordinates (using TEXCOORD0, TEXCOORD1, etc) and having multiple textures set to the effect, but you can also use a single UV coordinate and simply scale it when working with terrain, especially if you generate the terrain.

A quick search on "hlsl multitexturing" gave me this tutorial which might be a good start for you.


I need it so that 1 part of my terrain has a certain texture and the only part needs a completely different texture. Not mixing 2 textures together.

Assuming your textures are both 128x128 what you can do is make a new image that is 256x128 (or 256x256), copy your first texture into the (top) left part of the new image, and the second texture into the right part.

Now you modify your UV coordinates on the mesh, the parts that want the first texture get their U halved (so it goes into the left part of the 256x128 texture) and the ones that want the second texture are halved and get 0.5 added (so it goes into the right part of the combined texture).

Your terrain should now render with 2 textures. You may notice some artefacts where you go from one to the other texture, this can be fixed by duplicating the vertices at the seam, so that the triangle that wants the left texture does not share any vertices with the triangle that want the right texture.

This wouldn't be referred to as multitexturing, seeing as how your only using one texture (which just happens to be a texturemap with multiple textures in it).

To solve it with actual multitexturing you would use two Vector3 UV coordinates, the z component would be used for weight, two textures (which can be your original two textures) and then a hlsl pixel shader that blends the two.

Since you can chose the weight of both textures you can chose to make a quick transition by changing z from 0 to 1 and vice versa for the second texture. This option has the benefit of allowing you to slowly blend textures in places when you want to, but the drawback of requiring a special shader which does twice the work of the single texture one (in terms of texture fetches).

float4 col1 = tex2d(texture1, uv1.xy)
float4 col2 = tex2d(texture2, uv2.xy)

float4 color = (col1 * uv1.z) + (col2 * uv2.z) / (uv1.z + uv2.z)

You can also split the mesh into multiple parts, this allows you to use the same textures as in the multitexturing version, with the same shader as in the single texture version. But requires two draw calls instead of a single draw call.

Simply go through each vertex and if it needs the first texture, add it to the first mesh, and if it needs the second vertex, add it to the second mesh. Make sure that the edge vertices, between the two textures, are duplicated so that you do not get any holes in your terrain.

This is the simplest option, but making a texturemap would have better performance and multitexturing would be more flexible (such as going from all grass to gravel can be done smoothly instead of having a sharp line, where you chose to do so)

share|improve this answer
    
You are close to what I am talking about. But not really. I need it so that 1 part of my terrain has a certain texture and the only part needs a completely different texture. Not mixing 2 textures together. –  dvds414 Aug 20 '12 at 19:10
    
I have 2 TEXCOORDs but now I need it so the color.out variable in the pixel shader can display both of the textures that are being referenced using sampler2D –  dvds414 Aug 20 '12 at 21:31
    
The "normal" way to solve that would be to either make a texture with both textures in it, thus one UV can pick between the two textures, think a character model texture where face/clothing/eyes are stored in the same texture but at different coordinates in the texture. The other "normal" option is to split the terrain into two meshes, that way you can set the texture for each mesh separately. With multitexturing you can provide a weight with the texcoord, use a vector4 with w being the weight, this way you can both blend and do quick swaps between textures as you need –  Daniel Carlsson Aug 21 '12 at 1:01
    
well the first was is what i have been attempting for days and its not working right and just doesn't seem worth it anymore. The second way was the better way I was looking at. Do you have any suggestions on how the code for that would look? –  dvds414 Aug 21 '12 at 2:21
    
@dvds414 I edited my answer, it was getting too much for comments –  Daniel Carlsson Aug 21 '12 at 14:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.