Terrain texturing

Started by Rene, November 29, 2009, 20:51:35

Previous topic - Next topic

Rene

Hi all,

I have two questions concerning the texturing of terrain.

The first is how to texture the terrain in a cell-based world in an efficient and easy-for-world-creators way. By a cell based world I mean one where you have this huge world, divided into smaller parts so they can be loaded when needed while the game is running. How would I texture this kind of terrain? I think storing the whole map is horribly inefficient, so that's a no go. How about generating the texture according to a script when the cell is loaded? Or smart multitexturing? Or some other way?

The second question is about tile based strategy games. I remember the map editor of a certain RTS, Empire Earth to be precise. In this game the map is made out of quads, and you can give each quad a different texture. If the adjacent tiles have different textures, they get blended. I think you know what I mean, if not, here's a screenshot I found on the net:
http://www.hasweb.nl/~mylink/EEtoon29.jpg

In my engine, everything gets sored in VBO's. So to replicate this effect, I would need to create a different quad for every tile, and set up multitexturing when needed? Or is there a better way to do this as it would give a huge amount of VBO's, and in a worst case scenario six textures on a single quad.

Thanks in advance.
When I am king, they shall not have bread and shelter only, but also teachings out of books, for a full belly is little worth where the mind is starved - Mark Twain

dronus

I think the classic way would be to texture every tile. That would be quite inefficent. However, it could be solved like this:

-Split the landscape to four meshes, each one containing one of four adjacent tiles. So if you think of your terrain as 2x2-tiles, you got one index array for each the top-left, top-right, bottom-left, bottom right quad. Alternatively you could split up the mesh to single quads in one single index buffer by putting each vertex index four times.
-Thus every quad is not anymore connected, and now could use distinct texture coords.
-Put together all your tile textures into one large texture.
-You can now assign the texture tiles to your quads just by setting the texture coordinates, eg. cut the tile out of your large texture map.

Now you just need to bind one large texture, all four meshes are then rendered with the same gl texture.

I think that games that blend tiles maybe just use a max. of two layers, eg. blend water into ground. This then only requires two texture layers.


Faust

I made something similar. I wanted different repeating textures for a terrain and smoothly blend them into each other as well as mix them.
Using shader this was really easy:

I used 3 texture stages for 3 different textures: gras, rock, sand.
In addition i created a texture which defines the mixture of the textures. Red defines the percentage for gras, green for rock, and so on.
Within the shader i got the color from mixture, normalized it and mixed the fragment color from the detail textures. I used the only 1 texture coordinate set (whole terrain was within 0.0 to 1.0) but scaled it for the detail textures.

If you want something like the terrain effect on the screenshot, you could create a single texture with 16 RGB detail textures within (taking a single 2048x2048 texture would result in detail textures of size 128x128) and use the alpha channel as mixing table. A 0 stands for the first detail texture, 1 for the second and so on. The default linear filtering of opengl blends the different detail textures for you. You end up using a single texture for a map.

Kunan

I'm not sure if this is what you are looking for, but instead of using the vertex texture coordinates you could do everything in your pixel shader using a world matrix and a control texture (a texture that for each value of, say, red states a different texture should be placed, each pixel representing a tile of the map). This would give you an efficient means of storing and rendering your tile-based textures, and you could have it so when the pixels world matrix approaches the border of a tile, it blends the nearby texture. Plus, if your tiles have been set up to be in increments of 1 in worldspace, the tile's worldspace values for its pixels will map 0-1 just like the UV coords of the texture  :)

A detailed HLSL + XNA tutorial can be found here: http://allenwp.com/blog/2010/05/06/simple-fast-gpu-driven-multi-textured-terrain/
The concepts behind it should be simple enough to translate over to OpenGL. I've never used opengl, just happened upon here via googling  :)