Applying textures to tile-based terrain

Ok, this surely is one of those stupid newbie questions but after having read all kinds of documents on terrain rendering I’ve got an idea how to do LOD geometry and all kinds of other stuff but the thing that stumps me is texturing large terrains.

Of course you could go for one big texture that you “drape” over your terrain either with or without a high-detail “noise texture”, but that’s not what I’m looking for.

What I want is a tile-based terrain where each tile can have its own texture. The problem that I have is that the only way to render this I can think of is also the slowest:

so far I used plain GL_TRIANGLES and bound the correct the correct texture to each triangle. This works of course and putting everything in a display list speeds thing up as well, but…

it is too slow!

Switching to just one big texture and rendering the terrain as one big triangle strip speeds things up immensely. Using vertex arrays manages to squeeze out even more Fps.

But I just can’t think of any way of using the speed I get with triangle strips / vertex arrays with the ability to choose a separate texture for each triangle.

I must be overlooking a possibility somewhere. Anybody feel like pointing me in the right direction? :slight_smile:

PS: While writing this I suddenly thought of a possibility: maybe I could use one big texture that contains a whole lot of smaller textures and then use the texture coordinates to select the (sub)texture I want to render? Of course this still leaves triangle strips out but at least I could use vertex arrays or even vertex objects which I assume are still quite a bit faster than a bunch of glVertex calls each frame.

Changing texture is quite expensive. Your tile based terrain would run faster if you “sorted” the triangles based on texture. What I mean is that for each texture you render all the triangles that uses that texture. Using a large texture that contains lots of smaler textures will have the same speedup effect. There will be less texture changes because there is less textures.

Useing vertex objects with static data is the fastest way to render your terrain. Then most likely all the geometry is stored on the gfx card memory.

For wurm online, I generate new textures on the fly.

I render the normal tile textures textures for the area the new texture should cover either into a 64x64 area of the framebuffer or into a pbuffer, then copy that data into the texture. Then you can drape that texture over a larger polygon without having to do special tricks or multitexturing.

[edit: I lied, it’s not 256x256 pixels]

You talk about an “area”, does that mean that the 256x256 texture you talk about spans several “tiles”? Or do you dynamically make a texture that is used for just one tile?
Do you reuse these generated textures or are they too specific for the area anyway?

The area is a number of tiles.

For lod 1 (lod 0 is two tris per tile) in wurm, each “area” is 2x2 tiles, lod 2 is 4x4 tiles, and so on. Each area has a dynamic texture that’s specific for that area, but it would be a good idea to share the textures if possible.

So how do you handle(blend) terrain changes that occur on area boundaries?

And what was the reasoning behind this way of doing things? Because if I understand correctly you’re doing a kind of software-multitexturing? Does HW multi-texturing have some limitations you could not live with? But doesn’t the performance drop rapidly if you use lots of generated textures? (I imagine they have to be sent to the Gfx card again for each frame)

Questions questions questions :slight_smile:

The textures are generated by hardware, not software, and by doing it once (or, well, whenever the tiles in the area changes), I can reuse the rendered texture over several frames, thus gaining a lot of speed, and the possibility to use the other texture units for other effects such as lighting.

The terrain blending stuff is rendered onto the new texture as well.

Ah, so if I understand correctly the texture is being generated using not only the tiles it will cover but also taking into account the tiles that touch it at the borders?

There’s one thing I don’t understand completely with respect to areas: are they always the same virtual size? So a LOD 0 area at a large distance consists of only 2 tris while a higher LOD has progressively more tiles? But only one texture is generated? So textures at LOD 0 are equally detailed as the ones at higher LODs?

Textures have lower “resolution” at lower levels of detail. They’re still the same size, but they contain more and smaller subtextures.

And yeah, each tile texture is blended with the surrounding tile textures. Exactly how I do this is described somewhere on the wurm online forums.

[quote]Textures have lower “resolution” at lower levels of detail. They’re still the same size, but they contain more and smaller subtextures.
[/quote]
Ok, so I understood it wrong then? An area is not the same virtual size at each LOD? Because if its virtual/world size remains the same I would have thought that underneath it still covers the same amount of tiles.

So that’s not the case? It works just the other way around then? An area at LOD 0 has the smallest virtual/world size while higher LOD areas span progressively larger parts of the world?

[quote] And yeah, each tile texture is blended with the surrounding tile textures. Exactly how I do this is described somewhere on the wurm online forums.
[/quote]
I know, I read that one several times already ;D

For those who are interested, the thread with that info can be found here: http://www.wurmonline.com/phpbb/viewtopic.php?t=20

Yep, the lower the lod where the texture is, the bigger the area it covers is.

Aha, I’m beginning to understand (finally ;))

This sounds a lot like CLOD if I’m not mistaken.

How long do you keep the textures around? As long as they are in “the neighbourhood” of the client? Or do you have some kind of cache with an expiration algorithme?

They’re always kept around, as when you move far enough left for one to “vanish” to the right, another one is added to the left.

Kinda like a 2d cyclic buffer.
(there’s some overlap in the middle of the areas where the higher lod textures are used, but removing that would mess up the code waaay too much)

Ok, those are the buffers themselves, but the contents in them gets wiped out the moment:

a) it drops off the right side and gets reused on the left side
b) the terrain changes

Is that correct?

If so, I know enough for today :slight_smile:
Thank you very much for all the answers, I appreciate it a lot!!

correct.