Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Mephs

Ultimate terrain texturing thread

This topic is 5122 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Heyas all, Well, I'm writing this thread as I'm pretty annoyed with my current terrain texturing. It looks pretty cool, but I'm sure it could be better, and more efficient. To kick off the thread, here is a current picture (more recent than in the terrain screenshot thread) of my terrain @ 1024x768 resolution, 16 bit colour. As you can see, I'm using Charles Blooms' splatting method. That is 8x8 chunks of 33x33 vertices. Each chunk has a splat struct for each texture layer, consisting of an index buffer for that texture layer and an alpha texture. Each quad is assigned a texture layer, then the alpha map is generated based on the weightings of neighbouring elements. Finally an index buffer is generated for each texture layer that encompasses all quads of a given texture layer, and all quads adjacent to those (for blending). Now this is all well and good, looks pretty cool, but there are a few cons which I will go into detail about now. The more textures you use, the more splat alpha maps you need, though in theory you could have 9 alpha textures for every quad as that would cater for the texture from the central element and its neighbours, however, that is still a hefty nine 64x64 textures for every chunk. (which is 9Mb of alpha textures alone in my current setup). I would like to be able to increase, or remove the limit on the number of textures. This is not a necessity though, as I know vegetation will detract from imperfect terrain texturing, though it would be nice to have scenes with little vegetation looking just as good. View distance is also a pain in the butt. Working at a scale of 1 unit = 2 meters. 2 units per quad. That makes my terrain currently 2x2x32x8 = 1024 meters. As it is streamed, this will have to be halved as the player will effectively be in the middle of the terrain, making the view distance roughly 0.5 km. Now if I wish to increase the view distance, memory consumption will increase drastically, and most likely performance will decrease drastically as well, especially bearing in mind that to keep splatting looking correct, it may be fiddly to implement LOD schemes. Memory consumption as it currently stands for 256x256 vert terrain buffer (with some duplicate verts): Alpha maps for unlimited textures - 9Mb Vertex buffer @ 32 Bytes per vertex - 4.26 Mb (1 system copy for ray testing) say ten 512x512 texture layers (32 bit colour) - 10 Mb Index Buffers - 0.75 Megs Well, I wont go into every tiny detail, but thats a total of roughly 24 megs, not even including several necessary other components. Now, that's not bad, but consider this. To increase my view distance from 0.5 Km to 4Km, it requires 64 times the amount of data I currently have - 24x64 = 1536 megs!! So as you can see, it's looking unfeasible to increase the size by any great amount. But I don't know, is 0.5 Km a bad size? I'm not sure. So what I'm looking for is possibly a way to cut on memory consumption (I only wish it were possible to store all the alpha values in a single texture or something like that). Another issue is that of texture tiling. If I have the splat textures tiling very frequently, the resolution looks amazing, but the texture looks increasingly worse due to it becoming more apparent that it is tiled. The only way to combat this is to make textures very bland and smoothe, which defies the point of trying to get more detail out of it. You can use Yanns suggestion of tiling the texture very frequently, then tiling it infrequently such that it becomes its own detail texture, but this has a bit of a side effect of sometimes making the terrain appear discoloured when you want it to be more regular. Now on top of all this, my frames per second is a big issue. Currently, at 800x600 resolution, I max out at about 65 FPS, which is limited by the fact I'm using an MFC window with message loop (not refresh rate), and at worst case I can be down to 20-30 FPS ish. I don't even want to consider FPS impact upon increasing view distance!! Now this isn't bad for the level of detail I'm achieving, but it could be better I'm sure. So what I want to achieve is as follows: Possible pixel / vertex shader use - but with a fallback for pre-GF3 cards that still looks reasonable. Lower memory consumption Increase framerate Possibly increase to 1024x1024 texture layers Reduce tiled appearance Increase view distance All that and I still have lighting to implement (though I have temporary slope base vertex lighting, which looks ok, but nothing special), and I'd like to be able to acheieve framerates that would allow me to actually use this terrain in a game, I'm not looking to make this a pure tech-demo. Is it possible to achieve this? I think I may have summed up 90% of the terrain texturing posts on this forum in one, so it'd be nice to see if we can't beat my last thread on creating detailed terrain under sever limitations (hugely popular reference due to Yann!). PS I'm using DirectX 8, with GeForce FX 5700LE 256 Mb card, 256 Mb RAM and Athlon 2400 processor, though looking to make something that would still work on something like: 1Ghz processor, Geforce 4+ 64mB VRAM, 256+ megs RAM Cheers, Steve AKA Mephs [edited by - Mephs on June 10, 2004 1:31:32 PM]

Share this post


Link to post
Share on other sites
Advertisement
If you''re trying to make a practical engine for a game that runs on low-end hardware, you''ll have to set your goals lower. Even the latest high-end games don''t have unlimited textures on terrain and all that.

Techniques like those discussed in the "severe limitations" thread are probably more common... Eg. pack four detail textures into one RGBA texture (I think Yann talked about something like this), use a larger RGBA at 1 texel/vertex to blend between them and multiply the whole thing with another big texture that has the terrain color in it. You can do this in one pass and still have some fillrate left for vegetation and sky rendering.

Ultimately, art rather than tech determines how "good" your terrain looks. Your screenshot has three different textures that don''t fit together all that well, and they''re not arranged in an aesthetically pleasing way. The same tech in the hands of a good artist (= better textures, better heightmap..) would probably result in something a lot more interesting.

Even programmatically there''s a bunch of things you can do, like texturing based on slope rather than just altitude. Definitely add lighting and fog. Experiment with your noise generator too; try non-linear noise scale to exaggerate mountain peaks, blend multiple noise generators for different terrain types and so on.

(Minor optimization note: if you switch to a normal map rather than vertex normals you''ll save 8 bytes per vertex)

Share this post


Link to post
Share on other sites
OK, some minor discrepancies to point out here first off.

Vertices do not include normals at present. Texture blending can be edited realtime, so auto-generation isn''t a big worry (I know it looks wrong at the moment, but that''s simply because I have been focusing elsewhere than auto-generation.)

On the other hand, I think you may be correct in saying that I need to set my goals lower, however, even with that in mind there are some things I consider possible to do, but that I perhaps haven''t done them in the most efficient way, as I have seen several great looking terrain engines that outclass my own by a fair amount even without vegetation(FarCry, Realms of Torment/Krel/whatever it''s now called,Everquest 2, etc etc) OK I know I just reeled off a list of big names that are hard to compare to, but I know that it''s possible to improve on what I have, and I''m just trying to work out how, even if I don''t actually implement them, it would be nice to have the knowledge.

Unlimited texture numbers as I mentioned, is not necessary but desired (by unlimited I really just mean a large enough amount that an artist would have a lot of freedom). View distance is something I''m pretty sure I can increase.

Texturing the terrain using a large texture and several detail textures does not appeal. For starters you''re limited to four textures (which get boring quickly). Secondly, even if you work more into the equation somehow, the detail at a distance may look ok, but monochrome detail textures means that up close, you don''t really see anything in the way of real detail compared to what you do with splatting. A monochrome detail texture over a color map simply doesn''t look as detailed as a normal high frequency texture.

Anyhoo I could go on rambling all day, but I''ve gotta get back to work on it... have a few ideas to try and implement and what have you!

Cheers,

Steve AKA Mephs

Share this post


Link to post
Share on other sites
Hi,

Just a few comments make of them what you will.

Firstly i''m rather surprised by your splat alpha texture size, using 9x64x64 per chunk is quite extreme to me. In my own versions i''ve gone for much less resolution actualy to be one pixel per vertex. So in your example that would be a single 32x32 texture per chunk. As you can see vastly cutting down your texture memory requirements.

However I can fully appricate that you''d want more resolution than that and maybe should with your 4m sq quads. As to how much thats for you to decide and the purpose of the game. If on foot then I would have thought a splat 0.5m sq would be sufficent (requiring then a 256x256 alpha texture per chunk), if driving then you might get away with 32x32 or 64x64.

As to LOD I wouldn''t have thought this would be a great problem as the splats are done via textures and being chunked you can just have several index LODs to switch between for view distance. I think there was a good paper/pdf by someone at Muckyfoot about chunked LOD i''m sure it will turn up with a search in google.

Finally concerning tiling, this is a problem you''ll always face, but I seam to remember a solution involving using different tiling for different textures and overlaying two similar types of textures. That is for say a rocky path which might show tiling, have two types of rock and mix them to form the path. If they have different tiling frequency you should be able to disguise the tiling effect.

You may also want to look up an article (on gamasultra I think) about using the High band pass to reduce the prominance of tiled elements.

Share this post


Link to post
Share on other sites
I don''t have Far Cry so I''m not too familiar with the engine... But from what I''ve read, the level editor generates a huge texture (color+lightmap) to cover the entire map just like Battlefield, and detail textures are used when up close. That''s what the screenshots look like too. Are you sure it does something more advanced than that?

Share this post


Link to post
Share on other sites
I think it''s safe to assume that at least half (if not more) of gamers within the next year or so will possess a shader-capable card.

Using shaders, you can, effectively, create an "unlimited" variety in your textures (or close to it). This is only going to become more true as time passes, as I doubt any hardware will be released (well, short of those shitty intel boards that they stick in low end computers) in the near future that won''t support it (or some evolution thereof).

Personally, I''m going a wholly different route. Traditional terrain rendering methods are simply not very good for realistic outdoor simulations. Reality doesn''t allow for only concave geometry, for example. Lets not even get into the requirements for having a wholly different rendering technique for objects that aren''t part of the terrain itself (e.g. buildings).

Share this post


Link to post
Share on other sites
Heyas,

Okay, @ Etnu first as your reply most intrigues me. Do you have any screenshots of your method? I like the sounds of your method detailed in another recent thread with the idea of ''materials'' and such like. I''d love to see how it looks if you have anything fully working yet? I can host an image if you need it?

As for Farcry, it may well use a single base texture, but I recognise that it has a failing in memory consumption, in that the method it uses is likely unfeasible for large scale terrains. Say a base texture is a 32 bit 1024x1024 texture over a 1024x1024 heightmap, and you have 64 heightmaps(64 x 1024x1024x32-bit = 256 megs). Thats just for one pretty large sized map, so an RPG game as I hope to make is going to be struggling with that kind of consumption. So anyhoo, I accept it may not be a very relevant example, as it''s really built for a different purpose than most outdoor engines (small FPS levels rather than vast areas).

As for 64x64 alpha maps, this is as Charles suggests, and I think the extra bit fo resolution for the alpha maps make enough of a difference to warrant having them that size (4 texels per land element offers a blend that is a bit more finely controllable(sp?). Chunked LoD, hmm, something possibly worthwhile looking into.... I''ll et back to you on that one, but thanks!

Coming back round to Etnu, I''m convinced you''re correct aswell, though I have yet to implement any form of shaders in my terrain, I do think that it is the way forward, and the answer to several of my problems. I get the rough impression, that it will make it simpler and more efficient to render blending effects through a shader than through standard means.

Based on feedback thus far, here are my new goals:

1. Implement shader system,
2. Slightly increase view distance,
3. Reduce memory consumption,
4. Increase framerate,
5. Stick with around 5 textures per map (if FarCry can look stunning with 3 or 4 or so textures variations or whatever,
then it can''t be too important)
6. Reduce tiled appearance.

To achieve the above I will

1. Learn shader programming!! (e.g. I can load less alpha maps if I fade them out and turn off after a given distance, which I think could be done in a vertex shader that generates vertex alpha as a function of distance from viewer?)

2. Look at reducing per-chunk memory cost

3. As above, but also optimise my terrain buffer to a circular buffer rather than a square one, possibly look at streamlining existing methods to reduce consumption

4. I''m actually stumped on this. Though currently I use 2 passes per splat texture, which could be a single pass on my hardware (keeping the 2 pass option for backward compatibility). Don''t think it would make too huge a difference though, as effectively it''s rendering the same gemoetry over and over which shouldn''t be too bad? Possibly look at chunked LoD as suggested.

5. ''nuff said.

6. Vertex shader should manage this by implementing alpha map fade out, I''m still not 100% convinced by the multiple tiling frequency method (it just doesn''t look quite right). This was a major unrealised obstacle, I couldn''t work out why my terrain didn''t fade to base map in the distance, but have realised it''s due to not being able to have any real control over mipmap fadeout, and needs to be finely controlled in vertex alpha.

Hmm, any further suggestions?

Thanks for the input thus far though,

Steve

Share this post


Link to post
Share on other sites
Yeah, I'm no artist, but I did a few shots to demo stuff.

I suck at shaders, too (my first project using them), but the flexibility of the system means that I can always get other people to make my shaders for me :-)

Here are two shots of the exact same place on a map. The first has my "terrain" material applied. The terrain "material" isn't a d3d material. It's more like a real-world material. It consists of a vertex shader, a pixel shader, textures (3 in this case), and various properties used for setting render states and the like.



The second "material" ('dead grass') has no shaders (defaults to using FVF codes), 1 texture, and lets d3d do the lighting.



These actually use the same texture for the grass (the "terrain" shader applies a modifier to reduce the blue & red color channels in the first shot to make the grass greener).

I'm still working on my level editor though, so I haven't been able to do the really cool stuff that the engine allows, like buildings, water, caves, and the like.

One other thing neither of those shots show is how the material system can be used on EVERYTHING in game - even the interface itself.




[edited by - Etnu on June 11, 2004 2:43:27 AM]

Share this post


Link to post
Share on other sites
One other thing of note that neither shot shows is that every "face" in the map can have a different material. A face is usually a single triangle, but it doesn''t have to be. Faces don''t have vertices of their own, but rather indexes into a large index buffer (that way identical vertices can be reused). Faces are concocted when the map is loaded into several arrays of indices (1 for each material used in that particular node). Each frame, the nodes are tested for visibility first, and then they add their indices into a dynamic buffer for each material they contain (sorted by material).

I''m currently only using 1 vertex buffer (static) and 1 index buffer (dynamic) for the whole map, but I''m considering having individual buffers for each node of the octree for a performance boost, though I don''t think it''s quite necessary quite yet as I''m still getting about 300fps on a map with about 1.5 million faces, and I don''t think I''ll have too many more polys than that, so I''ve got plenty of leeway for character models and such.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!