Memory-efficient tiled terrain?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!

Memory-efficient tiled terrain?

Postby Bl00drav3n » Wed Apr 25, 2012 2:48 am

I am trying to implement a tiled terrain using Irrlicht, but I ran into problems. Currently one tile is made up from two triangles that form equilateral quads. To minimize memory costs, I am using four vertices for every tile that get shared with adjacent tiles, with the indexbuffer containing the indices for the two triangles (for example the first tile is made up from the sequence [0, 1, 2, 2, 1, 3]). In addition to that, I am also using a texture-atlas that contains several different tile-textures. The problem now is obvious: how do I render the primitives efficiently with the correct texture attached to them, without giving up the shared vertices between tiles (the corner of each tile appears in four triangles, if it's an inner tile)?

With shared vertices I can only set one texture coordinate to each vertex, so I already got the problem, that my textures get flipped horizontally or/and vertically depending on the tile-number (that is obvious, because for example the texture.u-coordinates of the vertices in x-direction is 0-1-0-1-0..., so the first tile-primitive got texture-coordinates interpolated from 0 to 1 and the second from 1 to 0, so the texture appears vertically flipped in the second tile). I addressed that problem already by using four different indexbuffers together with four corresponding texturematrices that flip the texture coordinates of the tile's vertices (the four matrices are identity, flipU, flipV and flipUV).

So I got rid of that problem, but another one remains: I'd have to change the texture for every tile and couldn't use something like driver->drawTrianglePrimitiveList for all tiles (because after every tile I usually have to change the texture). One solution to that would be to sort all indexbuffers, so that I can perform a single setTexture() call for all the tiles with the same texture, and just iterate over all the different tile-textures.
The problem with that solution would be, that it's probably not very efficient if the tiles are allowed to change their texture over time, for example if I wanted to write a terrain-editor where I can just "paint" the texture onto one or more tiles at once. Every time a texture changes, all indexbuffers will have to be sorted again.

On the other hand, if I used four unique vertices for every tile, I wouldn't have any of the stated problems, but two others:
1) The memory usage would go up (what I wouldn't like to let happen).
2) In a terrain-editor, if I wanted to change the height of one tile, I would have to identify all the corner points of that tile and all adjacent tiles and change their height (what may result in messy code and maybe performance issues?)

So my question now is: Can you help me identifying the optimal solution to address the above problems or do you have any other suggestions as to how to implement such a tiled terrain? I'd like to hear your opinions!
Bl00drav3n
 
Posts: 48
Joined: Sun Apr 22, 2012 11:55 pm
Location: Vienna

Re: Memory-efficient tiled terrain?

Postby hendu » Wed Apr 25, 2012 8:19 am

You don't need unique vertices, or in fact texture coordinates at all, if you place the textures in your shader according to some other metric, like position.

Tri-planar mapping is one solution.
hendu
 
Posts: 1552
Joined: Sat Dec 18, 2010 12:53 pm

Re: Memory-efficient tiled terrain?

Postby Bl00drav3n » Wed Apr 25, 2012 11:17 am

That is a good point, but how do I decide what texture should be drawn? Should I create an additional vertex-attribute buffer to determine the texture-offset or sample-coordinates?
Bl00drav3n
 
Posts: 48
Joined: Sun Apr 22, 2012 11:55 pm
Location: Vienna

Re: Memory-efficient tiled terrain?

Postby hendu » Wed Apr 25, 2012 12:12 pm

That's up to your imagination ;) Maybe use one texture to mark which other textures are used. Or use the height. Or noise. Or the number of the rendered frame. Or the date and position of the moon.

But yes, having the texture number as a vertex attribute is good too.
hendu
 
Posts: 1552
Joined: Sat Dec 18, 2010 12:53 pm

Re: Memory-efficient tiled terrain?

Postby Bl00drav3n » Wed Apr 25, 2012 12:41 pm

Okay, so I will try it this way: To every index there will be a 2-float texture-coordinate that determines which subtexture of the texture-atlas will be sampled inside the fragment-shader. I think I will have to write a simplification for S3DVertex as I will not need those TCoords. At the moment I don't know how to use vertex-attributes with Irrlicht, though.

Thanks for the tips! :) If anyone got some more suggestions, please let me know. :D

Edit: On second thought, I think with this method I got the same problem again - every vertex can only have a unique vertex attribute. What I would need is a buffer that sets the values on primitive-count (not vertex-count). I could also use a uniform that tells the shader how to sample the texture, but then I will have to sort the indexbuffer again. Maybe I didn't catch the idea as how to address that problems yet. :(
Bl00drav3n
 
Posts: 48
Joined: Sun Apr 22, 2012 11:55 pm
Location: Vienna


Return to Advanced Help

Who is online

Users browsing this forum: No registered users and 1 guest