Splatting question and terrain generator

Luth

07-04-2008 23:46:03

Hi!

I played around a bit with (Managed) ETM, Mogre and C# ... i liked it. What i'm trying to do is, to take a single (pseudo) random number and generate a complete terrain from it, so i can easily send level data over a network. My most important problem currently seems that i'm new to C#, 3D programming .... and ... well OGRE. :roll: Currently i'm only able to generate the heightmap and achieve, not good, but decent results, at least for the first try. On top of that i generate a texture with colour values based on the height of the map point. That colormap i want to use to decide which (splatting?) textures have to be used for that part.

(WARNING that picture is 600KB, sorry)


So the main question is, how to go from here. Can i use that texture directly to code for (at least) 4 other textures where to put them? Do i have to write new shaders for that and is there a possibilitie to generate and bind those other textures also on runtime?I would be glad for some hints in the right direction ... even through those questions may seem quite noobish. I just found little tutorials for ETM and how to use it's splatting technique or how to do such things manually.

Btw ... if anybody is interested in the (C#) Code-Examples of the heightmap generation or links to the C++ origins i used to write the C# code, let me know. Most of my part is not optimized and unfinished as usual, but working. Currently i have together:

- 3 (simple) algorithms to generate heightmaps
- procedures for merging, normalizing, smoothing, heightadjusting and flattening (or stretching) of maps


Thanks for the reading

SongOfTheWeave

08-04-2008 10:12:01

Sorry Luth, I've no idea what your question is.

Your procedural terrain ideas might yield some neat stuff, I'm working on some techniques for procedural generation of clouds (which is a bugger of a thing to do I've discovered since beginning.)

So, yeah, I want to be helpful but you lost me.

Luth

08-04-2008 11:05:23

Hi again.

Well ... maybe it was a bit too late for me yesterday. To clearify a bit what i'm trying to do: I want to have a "world map"-thing divided in lots of different regions. When a user clicks a certain region, that regions terrain and texturing is generated with pseudo-random numbers. To let it look the same everytime the user calls it, i want to use a certain seed for the number generator saved in a database. So the questions i have are the following:

Is it a usable approach when i'm working with ETM to
- Generate the heighmap
- Derive 1 or 2 "region maps" from that heighmap
- Use those as a ?coverage? map for texturing / splatting
- Generate lightmaps from it
- Trying to do that all together on runtime

So basically i want to know, if one of you has experience with such a concept ... or can hint me to inherent flaws of that approach together with ETM, that i might be unable to see at the moment.


The other questions are about how to do the texturing. As i said i have no experience with that 3d-thing. So if i undestood anything at all, i have to specify a terrain material, which i can do at runtime like with the simple colormap i used in the picture. The usual way to do this with ETM is to use splatting....which puts a number of textures on the terrain, depending on a certain coverage map. So the questions are:

1. Where do i specify how to blend what texture? In the shader programm, in the .material file or do i have to do it somehow in my code? Is there a "How to texture with ETM"-Tutorial or something?

2. If i use RGBA Colors for the coverage map i guess i should be able to specify the blending of at least 4 splatting textures. Is there a way to code more in there? Like maybe using values 0..127 in the red channel for one texture and 128-255 for a second texture? I assume 128 different blending states are enough...

3. Do i have to reinitialize the whole terrain- and swappingmanager when changing heightmaps, textures or lightmaps or can all of this be done with one instance of them?

4. Coverage maps should be of the same size as the heightmap if possible, right?

5. Is ETM able to save the resulting mesh, coverage maps and material or do i have to code that with OGRE functions or on my own?



Well ... i hope my questions are a bit clearer now. Or maybe there are some tutorials about using ETM i didn't find yet. :mrgreen:

Luth

CABAListic

08-04-2008 11:21:31

1. Probably you already know some of this, but to clarify: Splatting works by combining different textures (splatting textures) based on a weight for each texture. Let's say we have 4 textures which I'll name t1, t2, t3 and t4, and according weights w1, w2, w3, w4. Then the result of the splatting at a certain position is essentially w1*t1 + w2*t2 + w3*t3 + w4*t4. To produce sensible results, w1+w2+w3+w4 = 1 must hold.
The above stated calculation is done in the shader (though the ETM example shader combines 6 textures, not 4). But shaders do not care about the actual textures used, the textures are assigned in the material (which you can either specify in a .material script or you can create it dynamically at runtime). So what the shader gets from the material as input are:
  1. The coverage (or splatting) maps. These are also just textures, but their channels are used as the weights for the shader. [/*:m]
  2. The splatting textures, those are the textures you actually see combined on your terrain.[/*:m][/list:u]
    Or in short: The coverage maps specify *how* to blend the textures together, the material defines *what* textures to blend, and the shader does the actual combination.

    2. Your suggestion does not work. Each texture weight must be modifiable independently. But the R channel of a texture can only hold either the value 15 or the value 221 (as examples), not both at the same time. To really subdivide the texture into more channels than it physically has, you would need to divide by bits, i. e. of the 8 bits you would use 4 for the first weight and 4 for the second weight. But for one thing this is difficult (if at all, I don't know) to do in the shader, and for the other this leaves you with only 16 distinct values for each weight, which is most likely not good enough. So no, there is no sensible way to pack more than 4 weights in a single coverage texture.

    3. The TerrainManager currently can reinitialise, the new Terrain class in ETL v3 might not. It doesn't really matter, though, as deleting and recreating doesn't really add any noticable additional cost.

    4. Doesn't matter. Coverage maps should have sizes to the power of two, since many older graphics cards have troubles with other texture sizes. Making them of similar size to the terrain (i. e. if your terrain has 129x129 vertices, make it 128x128) is a sensible choice, though. The higher the resolution of the coverage map, the more detailed you can edit the splatting.

    5. ETM does not save the terrain mesh directly, but it can save the heightmap from which it can reload the terrain. Coverage maps can be saved. But the material is not ETM's concern, you have to take care of that yourself.

Luth

08-04-2008 11:51:50

Wow. Fast and detailed answer ... thank you!

1. Ok ... I understand a little better now how that works. So basically for each generated map i could, for example, use 8 textures, which are picked on runtime from several dozens to compose a terrain-material. Like 2 coverage maps with 6 splatting texures or such ... and use 1 coverage map for height-dependant and 1 coverage map for vegetation dependant texturing or similar.

2. Of course. :oops:

3./4./5. Thanks for the info. :mrgreen:

One more question :
I'm working on an pretty old 2.6Ghz Intel Celeron currently. If i'm using a 513x513 heightmap i need about 750ms to initialize the terraininfo, the splatting manager and material. Is that a reasonable time or am i doing something wrong here? Although I guess creating the mesh, texture coordinates and things from the 2D-heightmap takes some time ....

Great work that ETM btw.

SongOfTheWeave

08-04-2008 11:56:49

One more question :
I'm working on an pretty old 2.6Ghz Intel Celeron currently. If i'm using a 513x513 heightmap i need about 750ms to initialize the terraininfo, the splatting manager and material. Is that a reasonable time or am i doing something wrong here? Although I guess creating the mesh, texture coordinates and things from the 2D-heightmap takes some time ....


Sounds reasonable to me, especially if you're using a debug mode build.

btmorex

08-04-2008 12:01:30


2. Your suggestion does not work. Each texture weight must be modifiable independently. But the R channel of a texture can only hold either the value 15 or the value 221 (as examples), not both at the same time. To really subdivide the texture into more channels than it physically has, you would need to divide by bits, i. e. of the 8 bits you would use 4 for the first weight and 4 for the second weight. But for one thing this is difficult (if at all, I don't know) to do in the shader, and for the other this leaves you with only 16 distinct values for each weight, which is most likely not good enough. So no, there is no sensible way to pack more than 4 weights in a single coverage texture.


I think if you want to be crafty you can actually get 5 weights out of a single RGBA coverage map.

Texture 1: R
Texture 2: G
Texture 3: B
Texture 4: A
Texture 5: 1 - R - G - B - A

It complicates coverage map generation, but if you need exactly 5 terrain types, it's probably worth it.

CABAListic

08-04-2008 12:13:07

Yes, but this only works if you have exactly the number of textures and is not supported by ETM's splatting manager. It isn't even that much of a gain, because you need a SM2 shader for this, anyway, so you can just as well use 6 textures with two maps with hardly any extra work on the GPU.

SongOfTheWeave

08-04-2008 12:28:51

Yes, but this only works if you have exactly the number of textures and is not supported by ETM's splatting manager. It isn't even that much of a gain, because you need a SM2 shader for this, anyway, so you can just as well use 6 textures with two maps with hardly any extra work on the GPU.

What is the breakpoint for SM2 anyway Cabal? Is it more then X samplers? I thought that's what it was but, if you look at my FP declaration in my recent post about normal mapping (http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=6936) I have it declared as fs_1_1 (or fp, whichever it is.) it works, and I have the same number of samplers as the ET SM2 shader plus a whole ton of other parameters.

So, I am now officially unclear on what exactly the requirements for the 1.1 profiles are. The shaders in that thread work fine on my PC, but I do have shaders 2 capability. What's up with that? Does it actually work with the 1.1 profile, or is it secretly using 2.0+ and not telling me?

CABAListic

08-04-2008 13:11:49

Pixel shader 1.1 only supports 4 texture units and has some rather awkward restrictions (such as requiring a separate texture coord set for each of these texture units). 1.4 supports up to 6 units (I think), and SM2 up to 16.
There's also a restriction in the number of operations you can do, and older profiles have a more limited instruction set.

Luth

08-04-2008 15:54:59

Hah!

It works ... well ... at least kind of. Thanks a lot for the help!



Currently i only use 1 coverage and 4 color textures...and plan to expand that, after i have automated the generation of the coverage map a bit more. And i suppose there must be a way to prevent that one can see the tiling of the splatting textures that much? Is there something like overlapping for splatt-textures or should one use a second pass with another size or even other textures here?

The only approach i have read about was working with some kind of base textures ... but those would be tough to get, since i don't know exactly what the terrain looks like before it gets on the screen. :mrgreen:

CABAListic

08-04-2008 16:34:08

To reduce visible tiling you can either improve your textures or experiment with the splat scaling factors (i. e. how often the textures are repeated over the terrain). Not much else you can do.

SongOfTheWeave

08-04-2008 22:37:51

And i suppose there must be a way to prevent that one can see the tiling of the splatting textures that much? Is there something like overlapping for splatt-textures or should one use a second pass with another size or even other textures here?

It looks like your mountain/rock texture especially isn't tiling well. What I mean is you can clearly see the seams. The other textures you're using don't show their seams as obviously.

I'd take it into photoshop, offset it by half the imagesize in both directions so the seams (that were previously on the edges) are in the middle in a cross shape, then use the clone tool to smooth the seams.


On another note, how are you doing the water? Is that just another splatting texture or do you have a water plane? If so, are you "splatting" the water plane? i.e. a map that determines where the water plane exists, or is it just everywhere at a certain height?

Luth

09-04-2008 09:33:21

Good morning again.

And yes, those textures are evil ... i somehow thought, there may be a way in ETM to interpolate the edges of the tiling or use overlapping or something. In the meantime i experimented with some other textures and they look a little better ... although it's hard to find free seamingless texture stuff to use for the tiles.

I don't *do* water at the moment. I just took the transparent material example and have put a plane at 0.1 height, to check where water would appear at certain levels. Since this is kind of stupid, because you sometimes have lots of tiny "lakes" appearing, i plan to replace that with something customizable. Currently if i want to avoid having those lakes, i have to generate a coast/beach at one map edge (which doesnt look very natural currently) or move the whole map to a level above 0.1. To the things i want to test next, as soon as my time allows that, belong:

- check for and raise certain areas (or sub-maps) under a given medium height and size to remove small lakes

- lowering certain areas to have placable "connected regions" of a given size as lakes

- using several diffent sized water planes at different heights, to allow for coast together with larger lakes

- include natural looking rivers somehow :shock:

- bundle those things to some kind of meta post-processing on top of the raw map generation like
map.RemoveLakes(minSurfaceArea)
map.AddLake(x,y,SurfaceArea)
map.AddRiver() ...


But i suppose this will take a lot of time, if i get it working at all.

SongOfTheWeave

09-04-2008 09:56:38

- check for and raise certain areas (or sub-maps) under a given medium height and size to remove small lakes

- lowering certain areas to have placable "connected regions" of a given size as lakes

- using several diffent sized water planes at different heights, to allow for coast together with larger lakes

- include natural looking rivers somehow :shock:

- bundle those things to some kind of meta post-processing on top of the raw map generation like
map.RemoveLakes(minSurfaceArea)
map.AddLake(x,y,SurfaceArea)
map.AddRiver() ...


Like in SimCity 2000!

Luth

09-04-2008 10:12:41

Uhm .... huh? Why? Did they have a map generation like that? It's a long time since i played that one.

:mrgreen:

SongOfTheWeave

09-04-2008 11:13:34

Uhm .... huh? Why? Did they have a map generation like that? It's a long time since i played that one.

:mrgreen:


Yeah, it had a thing where you pick some parameters via sliders for how mountainous it is, how forested, how much water coverage, whether you want a coast, etc. It was cool.

Luth

09-04-2008 11:29:17

Aha. Cool.
That's pretty similar to what i want to do. Only difference is, that i want to define several map types with ranges/chances for the used parameters and pick them mostly random then. So no sliders for anybody. :)