In general, what would be a good approach to manage the rendering of these kind of things? Like grass and trees. For example i'd have a density map of some sort that specifies the location of the objects, but do i sample it in the GPU and use the result to translate, or read it in the CPU at initialization? Or is there a better approach?
Good way to manage grass rendering?
As a "general, high-level answer", yes you will certainly want to do such things as reading a density map as much on the GPU as possible. You will also want to use techniques such as instancing as much as you can.
And, you will want to cheat as much as you can. If you can get away with a texture map in the distance, do that. If you can get away with some raymarching in the intermediate distance, do that. If you can get away with billboards, use them. Only draw real geometry where you need it, because drawing all foliage using geometry will be insane amounts of triangles and overdraw.
The best "grass" paper that I know is from Kevin Boulanger. Definitively look at it.
I can second Kevin Boulanger's method. I'll also include example results of my own implementation of his method, so you can see some results.
Ad my implementation notes:
1.) I have basically just 2 grass tiles types - one with separate blades and one from slices (as opposing to kevin, he had more complicated LoD).
2.) Positions of tiles are generated as a grid on heightmap, in vertex-shader the grass is placed correctly on terrain. Animation is done also in vertex shader by bending the grass geometry (note that it's weighted by texture map).
3.) Height of the grass is driven by "density" map (e.g. the road). Note that if there is no density for given tile, the tile is skipped.
4.) Tiles use instancing, I have 2 lists of tile positions with additional parameters (one for high detail tile and one for sliced tile), these lists contains position, whether tile is flipped in X or Z direction (this helps to eliminate repetition pattern). Now I take just visible tiles from these lists (frustum culling using quadtree), and update those to vram. In current-gen you could also do this in compute shader (but it's not rly that much of data).
For large worlds, the tile data could be streamed from disk.
5.) It's very important to balance colors and lighting (so the seam between high detail and low detail is invisible).
6.) No grass shadowing & self-shadowing like in kevin's work, it was too expensive for my purposes. I preferred antialiasing to that (done through sampling alpha to coverage), FXAA doesn't work well for this kind of aliasing (result was blurry).
7.) Casting shadows on grass isn't as expensive in deferred renderers, in forward renderers it is expensive like a hell (tons of vertices) -> I used deferred shading for my project.
And just a last note -> SSAO works quite well with this grass.
If you have any questions about code, etc. I could give some (at least pseudo-code, so it would be easier to understand) out.
My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com
My concern is with the density map since my terrain is relatively large (30km x 30km). You're sampling the density map on the GPU right? If so, do you render the grass patch everywhere and use the GPU to modulate the height/skip grass or do you choose where to place patches on the CPU and use GPU to modulate height?
Also, what do you guys think of techniques that use geometry shaders instead of meshes?
http://illogictree.com/upload/site/LeeRealtimeGrassThesis.pdf
http://outerra.blogspot.com/2012/05/procedural-grass-rendering.html
One problem with geometry shader technique is directly mentioned in the first paper you link though without the author noticing:
Anu Kalra (2007) provides a method of using DirectX 10’s geometric instancing technique to efficiently render thousands of blades of grass
On 2013/7/4 at 9:34 PM, Vilem Otte said:I can second Kevin Boulanger's method. I'll also include example results of my own implementation of his method, so you can see some results.
Ad my implementation notes:
1.) I have basically just 2 grass tiles types - one with separate blades and one from slices (as opposing to kevin, he had more complicated LoD).
2.) Positions of tiles are generated as a grid on heightmap, in vertex-shader the grass is placed correctly on terrain. Animation is done also in vertex shader by bending the grass geometry (note that it's weighted by texture map).
3.) Height of the grass is driven by "density" map (e.g. the road). Note that if there is no density for given tile, the tile is skipped.
4.) Tiles use instancing, I have 2 lists of tile positions with additional parameters (one for high detail tile and one for sliced tile), these lists contains position, whether tile is flipped in X or Z direction (this helps to eliminate repetition pattern). Now I take just visible tiles from these lists (frustum culling using quadtree), and update those to vram. In current-gen you could also do this in compute shader (but it's not rly that much of data).
For large worlds, the tile data could be streamed from disk.
5.) It's very important to balance colors and lighting (so the seam between high detail and low detail is invisible).
6.) No grass shadowing & self-shadowing like in kevin's work, it was too expensive for my purposes. I preferred antialiasing to that (done through sampling alpha to coverage), FXAA doesn't work well for this kind of aliasing (result was blurry).
7.) Casting shadows on grass isn't as expensive in deferred renderers, in forward renderers it is expensive like a hell (tons of vertices) -> I used deferred shading for my project.
And just a last note -> SSAO works quite well with this grass.
If you have any questions about code, etc. I could give some (at least pseudo-code, so it would be easier to understand) out.
i'm implement grass effect in my game,could you show me the pseudo-code please