Forest Rendering
I'm currently planning a project that is intended to take place in a forest setting, and therefore have been looking into forest rendering.
Having found little by the way of middleware (within my price range, at least - I'd love to use SpeedTree, but I estimate that it's about two orders of magnitude out of my price range at the moment :/), I've been researching the matter of implementing it myself.
I've encountered a number of interesting ideas, and have a few thoughts, but, largely, I think, due to inexperience in level-of-detail matters, I feel that I don't yet have a solid idea of how to approach it, and am not confident in my estimations of the effectiveness of what thoughts I do have.
So, I come here in the hopes of advice. ^_^
First of all, if anyone knows of any middleware that might be of use to me, please do let me know - my aim in this is the creation of a game, not a forest rendering engine.
Otherwise, what advice have you on rendering forest scenes?
The specifics:
- My viewpoint is intended to be roughly eye-level, and I doubt that I'll have any points from which the forest is visible from above (the few cases that I currently have in mind in which the player might travel above the level of the tree-tops all, I think, involve features that should occlude the surrounding forest sufficiently).
- I am currently planning to include some degree of stylisation, increasing with distance, in the levels of detail, which may perhaps allow for greater decreases in complexity with distance than if I were aiming for a strictly realistic scene at all distances. That said, I do want trees viewed at close range to be very realistic. I'm willing to reduce or remove the stylisation if I end up using a piece of middleware that doesn't offer the feature, but which otherwise produces high-enough quality.
- I want forest density and composition to vary, although I imagine that this shouldn't impact on the rendering algorithm overmuch.
As to some of the research that I've done thus far, I've read this GPU Gems article, but am not sure, given that they seem to indicate the use of billboards, of how to then have leaves not seem to "turn" as the player moves about them at close range, always presenting the same view. I seem to recall one article mentioning alteration of the texture coordinates, but would that effect not be more easily achieved by simply using non-view-oriented billboards?
I've considered the possibility of using a volumetric function or map to place leaves, but am not sure of what, precisely, to do with it, or, for that matter, how to define it.
I've looked through Weber's "Creation and Rendering of Realistic Trees" (primarily the section on rendering), but am not sure at the moment of how to implement what he describes, at least in a way that is likely to look convincing. I do, however, like his idea of deriving a given level-of-detail from a single representation.
Finally, I've searched these forums - indeed, I think that some of the results that I found here led me to some of the items mentioned above - but thus far haven't found much by way of specifics.
You need a few elements that work together.
First, you have to have some kind of visibility system for easy culling of trees that not on screen, or are too far away. A quadtree is ideal for this; you can easily cull areas not in the view frustum, and or, depending on how you handle the z-plane, are too far to be drawn.
Then you need a decent sorting system; in a forest situation, presumably with alpha-testing for foliage, you absolutely must sort front-to-back.
Then you need an LOD system for the actual trees. This is where it gets complicated. I suggest using polygon meshes with alpha masking for trees up-close, using LOD to reduce the complexity of the mesh to some extent, and then switching to sprites at a certain distance.
Now to create the sprite LODs, you can use one or two levels in my opinion. In the simplest scheme you would just have one sprite rendered for each tree-type. In more a complicated scheme, you could use either multiple views for each tree and then switch between them for particular angles, or use dynamic imposters.
Dynamic imposters look best, but you can't draw the whole forest this way--you will only have texture memory for a relatively small number of trees--so you must still switch to pre-rendered sprites at a far distance.
I've implemented this method: mesh trees up close, dynamic imposters at mid-distance, and simple sprites at far distance. Using quadtree and 2 z-buffers i can render massive amounts of trees far into the distance with good framerates.
Actually creating the tree meshes themselves is another matter; many programs exist to model tree meshes, none are really satisfactory for in-game models (i've tried them all). X-frog produces the most realistic, but is also difficult to use but more importantly, hard to make meshes that aren't too high-poly or have a good mesh without too much overlap(which makes overdraw). I believe for instance, the trees in Crysis are hand-modeled.
This brings me back to a key point; the biggest killer in a modern engine with foliage is overdraw. Polygons can be managed, but overdraw is more difficult, even with sorting. Individual tree meshes can have lots of overdraw. Therefore, if you have complex pixel shaders, you might want to consider differed rendering.
First, you have to have some kind of visibility system for easy culling of trees that not on screen, or are too far away. A quadtree is ideal for this; you can easily cull areas not in the view frustum, and or, depending on how you handle the z-plane, are too far to be drawn.
Then you need a decent sorting system; in a forest situation, presumably with alpha-testing for foliage, you absolutely must sort front-to-back.
Then you need an LOD system for the actual trees. This is where it gets complicated. I suggest using polygon meshes with alpha masking for trees up-close, using LOD to reduce the complexity of the mesh to some extent, and then switching to sprites at a certain distance.
Now to create the sprite LODs, you can use one or two levels in my opinion. In the simplest scheme you would just have one sprite rendered for each tree-type. In more a complicated scheme, you could use either multiple views for each tree and then switch between them for particular angles, or use dynamic imposters.
Dynamic imposters look best, but you can't draw the whole forest this way--you will only have texture memory for a relatively small number of trees--so you must still switch to pre-rendered sprites at a far distance.
I've implemented this method: mesh trees up close, dynamic imposters at mid-distance, and simple sprites at far distance. Using quadtree and 2 z-buffers i can render massive amounts of trees far into the distance with good framerates.
Actually creating the tree meshes themselves is another matter; many programs exist to model tree meshes, none are really satisfactory for in-game models (i've tried them all). X-frog produces the most realistic, but is also difficult to use but more importantly, hard to make meshes that aren't too high-poly or have a good mesh without too much overlap(which makes overdraw). I believe for instance, the trees in Crysis are hand-modeled.
This brings me back to a key point; the biggest killer in a modern engine with foliage is overdraw. Polygons can be managed, but overdraw is more difficult, even with sorting. Individual tree meshes can have lots of overdraw. Therefore, if you have complex pixel shaders, you might want to consider differed rendering.
Thank you very much for your response. You've given me some interesting things to think about. ^_^
Hmm... Surely if I were to use alpha testing (instead of blending), with depth -testing and -writing turned on, then, given that only a small proportion of any given leaf is semi-transparent (the rest being generally either fully transparent or opaque), I should be able to get away with unsorted leaves, in the mid- to far- distance, at least. There would likely be errors at leaf edges, but since those account for a small proportion of the image, I would think, it shouldn't be too noticeable.
As to distant sprites, I suspect that stylisation might be of benefit here, potentially allowing me to use a limited set of distant sprites for a more varied set of meshes - if I have five meshes for a given tree type, I might get away with using only one or two distant sprites.
I'll admit that I'm very much considering a procedural generation system for the individual trees, since I would very much like to have a large degree of variation between trees of a given type - I don't want each tree of a given type to be a scaled and rotated copy of a one of a few meshes. I also wonder how many systems will support the additional render target or targets and texture memory.
If I do do so, perhaps I should go with the idea of creating varied-resolution versions at runtime based on the same internal representation of a given tree. Does anyone have any comments or advice on that?
Hmm... I believe that I will indeed look into deferred rendering, thank you - overdraw is indeed something that concerns me. I'm afraid that I've not yet learned shader-use, so I'll likely have a fair bit of work ahead of me to get there, but I believe that it should be worth it, to me at least.
Quote:Originally posted by Matt Aufderheide
... in a forest situation, presumably with alpha-testing for foliage, you absolutely must sort front-to-back.
Hmm... Surely if I were to use alpha testing (instead of blending), with depth -testing and -writing turned on, then, given that only a small proportion of any given leaf is semi-transparent (the rest being generally either fully transparent or opaque), I should be able to get away with unsorted leaves, in the mid- to far- distance, at least. There would likely be errors at leaf edges, but since those account for a small proportion of the image, I would think, it shouldn't be too noticeable.
As to distant sprites, I suspect that stylisation might be of benefit here, potentially allowing me to use a limited set of distant sprites for a more varied set of meshes - if I have five meshes for a given tree type, I might get away with using only one or two distant sprites.
I'll admit that I'm very much considering a procedural generation system for the individual trees, since I would very much like to have a large degree of variation between trees of a given type - I don't want each tree of a given type to be a scaled and rotated copy of a one of a few meshes. I also wonder how many systems will support the additional render target or targets and texture memory.
If I do do so, perhaps I should go with the idea of creating varied-resolution versions at runtime based on the same internal representation of a given tree. Does anyone have any comments or advice on that?
Quote:Originally posted by Matt Aufderheide
This brings me back to a key point; the biggest killer in a modern engine with foliage is overdraw. Polygons can be managed, but overdraw is more difficult, even with sorting. Individual tree meshes can have lots of overdraw. Therefore, if you have complex pixel shaders, you might want to consider differed rendering.
Hmm... I believe that I will indeed look into deferred rendering, thank you - overdraw is indeed something that concerns me. I'm afraid that I've not yet learned shader-use, so I'll likely have a fair bit of work ahead of me to get there, but I believe that it should be worth it, to me at least.
I believe that the reason front-to-back rendering was suggested was performance-related, rather than to achieve the correct look. By having nearby fragments shaded first, more distant fragments are more likely to fail the z-test and so they won't be processed unnecessarily. Performance issues due to lots of overdraw will most likely still be a problem, but perhaps to a lesser extent than if you were to use no sorting at all.
Yes, sorting front-to-back is needed to reduce overdraw. This is because modern video cards have "early-z" culling. Which means that in a case where you have a lot of overlapping geometry, rendering the stuff in front first is a big win Note: its very difficult to sort every polygon, so sort each batch. Sprites however, should all be sorted (fortunately this is easy). Sorting may have its own expense, but is a huge win for trees and such.
Of course this mean you must z-write, so no alpha blending; use alpha testing for foliage.
Of course this mean you must z-write, so no alpha blending; use alpha testing for foliage.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement