(Note that I've turned off the grass effect here for clarity)
not only this but it took a long time to generate texture pages which made moving around and changing things a bit painfull. The original desire here had been that one big unique texture would allow maximum freedom as you can put anything anywhere without fear of tiling artifacts or running out of memory - the memory footprint is constant. Unfortunately though I came to the thinking that this benefit wasn't actually worth the sacrifice in resolution and data generation time so I've been looking at replacing it with a more traditional tile based system. The art of course is to somehow do this without the nasty carpet-like tiling so often seen. I am still using a 128K x 128K clipmap based texture for the height and normal data but to this I have added blending weights for up to sixteen landscape tile textures which will represent the various grass, dirt, sand, rock, snow effects or whatever. Hopefully sixteen will be sufficient as even with this it's taking 12 bytes per texel.
During rendering, the landscape vertex shader unpacks these weights from the clipmap texture and passes them on so the GPU will interpolate them at the per-pixel level and the pixel shader can use them to read from an array of landscape tile textures for all non-zero wieghts, blending the read texture colours together for the final result. All these are blended onto a base texture (currently grass) so in effect there are seventeen actual textures in use.
Below are some screenshots of the new system, both performance wise and memory wise it's quite similar to the old one but it should be pretty obvious even to the casual observer that there is significantly more detail present - I'm working with a scale of 1 cm per texel for now:
The first version of this I had running used (512 x 512) landscape texture tiles which I had 'borrowed' from a released game, but even with my most careful fBm based blending between textures I found the tiling artifacts caused by the repeating texture detail most unsatisfactory. To improve this situation I employed the texture synthesis class I wrote to help produce unique texture detail for the old massive colour texture system I was replacing. Using this I produced new (2048 x 2048) tile textures using the original (512 x 512) ones as exemplars. Although this uses more memory (we're talking about 40 MB for the texture array even with BC1 compression), for the main landscape rendering I am happy with this budget, especially as it's not that different from the space used by the old clipmap system. The key benefits though are that it not only reduces the frequency of the tiling artifacts by a factor of four in each axis, it also reduces the visibility of the artifacts as the synthesised texture is by it's nature more chaotic.
As an example, below is one of the rock texture that I'm working with. On the left is the (512 x 512) 'borrowed' original, in the middle is a (2048 x 2048) version produced by simply tiling the original while on the right is a (2048 x 2048) version produced by the texture synthesiser:
as you can see, the middle tiled image shows a strong repetitive pattern very obvious when used in situ. By comparison, the synthesised image on the right while not exactly the same as the exemplar exhibits pretty much the same features but in a completely chaotic manner eliminating the tiling artifacts. Another bonus is the synthesised texture maintains the tiling property of the original so can be tiled as needed across the landscape.
Synthesis is carried out as an offline process during program startup with the results being cached on disk for subsequent runs. A lengthy pre-processing pass is carried out on the examplar (takes about an hour currently for a 512x512 exemplar on a single core HT machine) which generates an exemplar reference file which can then be used with various randomness parameters to generate different larger synthesised texture in about five minutes. The algorithm was originally adapted from a SIGGRAPH paper where it ran on a GPU so it could be sped up significantly but I find it easier to understand and debug new algorithms on the CPU first.
As the blend weights for the different textures are stored with the height field samples, they can be changed every 30cm or so which I think will turn out to be adequately fine granularity for good looking landscapes, and the fact that all sixteen tiles can be blended with various weights should mean no hard edges where path meets grass for example.
The other less major change in this version is a new grass texture. The one shown here is from an old nVidia sample which I think is better than the crobby one I had knocked up myself - I'm still not 100% happy with it but at least it's an improvement.
Anyway, I'm quite happy with the end result. The island now has much finer ground texture detail for about the same memory and processing footprint and while it's lost slightly in flexibility it's gained massively in visual appeal so I count that as a win.