Grass generationhttp://forum.devmaster.net/t/grass-generation/21637
Is there a better way to generate grass on a terrain without generating a zillion grass blade? I want to do this for static scenes, not real time.
Tue, 25 Nov 2014 21:06:08 +0000graphicsGrass generationno-reply@example.com (@Osprey_Cowan Robert Cowan)@Osprey_Cowan wrote:

Also I'd like to note that the grass rendering technology mentioned here is quite old, in the time I've improved the technology for better use and I'm working on new sneak peak application to show how I've advanced since the last time.

ok, I have almost getting it to work. I had to change my ways of coding glsl here. TheNut has been helping me get on the right track. I keep on doing the v1.0 deprecated stuff, and yours uses #version 410 and all my code errors out with tons of messages!

The target of this post is to show how-to implement basic tiled grass, I won't show how to optimize it further (even though I already had it implemented in program from which I posted screenshot), I'll give tips though; Also note I won't give lighting tips here (like implementing shadows, self-shadowing, global illumination, etc.) - why? Simply because this post will be huge as it is. Note that I can make a post or two about how to implement realistic lighting on grass, etc.

Okay the goal is to implement cool LODded grass like in my previous post on height map, it won't be as optimized or as nice (because that would just need another huge article-post) but it will work. So I assume we got mesh loading, texture loading, shader loading and camera classes (e.g. the base of "game engine" ready to work) - I'm implementing this in my own game engine, though I think it's easily adaptable to any other (like Unity, C4, etc. ... though I assume you have your own one)...

So basically we need our CGrass object that is used to store/render single grass cell (my meshes have 5x5 units):

Now this is actually very unoptimized - simply because we're actually just doing LOD + at some distance cutting it. Even though this will run enough fast even on my Core i3 + Radeon HD 5470 notebook (actually I've just been developing this on it). Optimizing it further by separating high LOD (mesh of blades) and low LOD (slices) each with separate shader and drawing them with instancing also gives quite a huge boost, I'll comment on optimizations further down.

2.) Rendering grass cells

So now we can render a field of N x N cells of grass (some 100 x 100 is quite huge for 500x500 terrain in my case - which is actually quite huge). I assume that the terrain rendering isn't the problem, so let's jump ahead to grass rendering...

In motion it looks like the ground is eating the grass (it's just scaling to 0). So I also will give you all the data files i've used (height map, obj model of terrain (which is actually just height map applied to plane and saved - in case u want separate model), all grass meshes & textures i've used, note that my grass blades are color-tuned in pixel shader (you can also fine-tune the texture, which is better for performance reasons)) - here u go http://www.otte.cz/grass.tar.gz

Okay as far as I can tell this works pretty well, although as I mentioned I'll discuss optimizations and fancyness a bit...

5.) The Optimization

5.1 Listing the cells Even though this is fast enough, it can be well a LOT faster. Start with separating grass cells that are meshes and slices to two arrays, on camera move push new inside and remove old out - you actually have two lists - mesh cells list and slices cells list. Render them separately with pre-binding all the textures needed (saves texture unit changes, because now texture bind changes every time a cell is rendered).

5.2 Instancing Second thing is to add instancing - this gives quite a huge speed boost and I would add it as one of the first features if i were you (the speedup isn't quite obvious in the first moment, but when you start adding more stuff (and I mean lots of more stuff) the speed difference between using instanced grass cells and uninstanced starts to be really obvious) - in scene I posted before (with the cottage and the stuff, instancing version is more than 2.5 times faster than non-instancing version).

5.3 Frustum culling Third thing is also speeding up everything - and thats frustum culling. Quite simple to implement (because this is actually a grid) - it gives a little boost (you actually render a lot less grass cells when camera is at ground level). If you really want to favor speed (as I do), make a quadtree on top of it - because this will decrease the number of frustum cull tests, by quite a huge factor.

5.4 Optimization summary So basically whole optimization can be shortened to - use some kind of hierarchy and frustum culling, render all cells in high detail LOD in single call (through instancing), the same goes for low detail LOD ... to achieve this you will have to keep lists of active grass cells. Note that you will need to rebuild the hierarchy often as you add/remove cells to lists - but it's actually quite fast, because building quadtree on N x N grid is almost instant (also you can guarantee that quadtree is easily buildable by merging 4 closest cells with little fine-tuning - e.g. using 16x16, 32x32, 64x64, etc. total cell counts).

6.) The Fancy Stuff

E.g. the hard part. Everything goes up and down with textures - my textures for the grass are bad (they don't have same colors for all LODs

although I fine-tune this in pixel shader). If you want to get this work good, create good textures. Then we can divide the work to lights & shadows and movement.

6.1 Shadows & Lighting Basically you divide the light to direct, indirect (from sky and other items) and transmitted (part of indirect). Direct lighting is simple (you can use normal maps to do it nice and easy, and still good looking)

using lamberts cosine law + phong for specular works quite well (note: don't forget that you need to light both sides of either grass blades and grass slices - so take absolute value of dot product). Indirect lighting is quite tricky - I personally use realtime instant radiosity with secondary shadows for everything but sky + visibility test for sky indirect lighting, for slower computers ambient constant or good SSAO works awesome ... for offline renderers you can actually use path tracing and the result will be very nice. Transmitted lighting is solved by either constant or texture - note that I ignore this effect on grass because it actually isn't visible enough. Shadows are quite tricky, because you can't use shadow volumes, neither shadow maps. What is quite useable are plannar projected shadows (or some texture hack is also useable) and texture for self shadowing (see Kevin Boulangers work on this). I've dropped shadows out, because I actually don't think that they're visible enough (e.g. it's not worth it

it actually doubles the polycount not giving good effect - it's barely visible)

6.2 Animation It's actually try&fail (in my case) - but for sure take grass position into account and do some sin/cos functions to get nice waving grass (don't forget using gradient texture as weight for grass! - so you wave just the tips of grass, not the whole blade/slice). You can also try using "wind maps" (I think I made a post here some time ago about them) with this to get waving in wanted direction. And dont try moving grass somehow differently when character moves in it - it just looks weird (I mean like in Two Worlds 2 for example).

So well, I hope thats describing all the stuff you might need for basic grass system implementation. If you would have any problem - feel free to ask, I'll try to help (even with optimizations & fancyness - because I've got mentioned things already implemented I can post a little how-to like this one).

Okay, time to continue on my crusade of making ProjectRPG!

EDIT: Some little changes in bold text, etc. - so it's better looking

EDIT 2: One more last note - you need to have multisampling enabled and some 2 or 4 samples - because I use transparency multisampling (sample alpha to coverage). In case you don't have, just use basic alpha testing instead of that - glEnable/glDisable GL_ALPHA_TEST and set glAlphaFunc to GL_GREATER and value to some 0.5f ... it will be more aliased, but I assumed that transparency multisampling is available on most computers nowadays.

I would really appreciate it Vilem. I've been pulling my hair for a long time trying to make something, and it seems so complicated, but yet, people like you just do it like it's easy! I feel kind of stupid. :wacko:

Actually it depends on machine and whether the algorithm is optimized (and correct). I can write a little article how-to here - because I have all sources (models, textures, shaders) on my HDD, and I can share them along with my algorithm implementation.

And also I can second that no OpenGL school is needed (I don't actually have any - though I had some OpenGL basics in school, though they all were deprecated stuff which is actually unusable... all you can do is self-learning, asking on forums, etc. (Note. I can't judge all the schools, but I think most would do it this way).

ok, I've tried but it's so slow I get 0.01 FPS it's crazy!! It should be at least 60 right? And it doesn't look anything like yours. Mine looks bad. I have a hard time to get the PNG transparency to work in GL, and then it doesn't get sorted properly or something, it look like crap. I give up. I need to go to OpenGL school. :ph34r:

I won just ranked Leagues of Legends - http://eune.leagueoflegends.com/ - ranked game . You know, one does need to "turn off" from programming by doing something else than programming.

Oblivion actually don't do it this way - it just renders the grass mesh where game creators specified that there is grass mesh (note that you can use brushes to draw them effeciently), whereas what I posted is a lot better in my opinion.

Basically for non-real-time graphics you would apply the same - although you will use full physically based BRDF/BSSRDF for lighting (actually you can do high-quality lighting in realtime, even with shadows - see Kevin Boulanger's work about that). So basically what Reedbeta wrote is the way to go.

So I finally get to reply (had 2 ranked matches at LoL - so it took most part of my evening - and most relevant information - won them :ph34r:). I also recommend quickly going through Kevin Boulangers work on grass rendering... http://www.kevinboulanger.net/grass.html

So actual idea is in dividing whole terrain into grid for grass coverage

this whole technique is just very good lod - near the camera you use actual grass blade meshes (for whole grid cell there is one mesh - transformed to fit the terrain), for further grass there are alpha tested "slices" (e.g. just textured quads) - horizontal and vertical planes - so it looks like actual mesh. The whole idea is in good transition of these LODs - so you get really nice looking grass.

What is so awesome on this technique is, that the pre-computed grass blade meshes for cell doesn't need to be just uniform grass - bam it looks way better with dozen of different "grassy" plants in it.

I actually implemented in on my own before reading the Kevin Boulanger's work (so imho it differs in some aspects), and I fine tuned it after I read it (if he reads this - then thanks Kevin, your tips in the thesis were very helpful).

So how it looks: (contrast for mesh has been increased so you see the border between mesh and slices)

Note: See the areas in shadow of the tree - slices can be visible in distance - you can avoid this by smooth transition between mesh and slices - though it's a bit slower than hard transition

Also don't worry about performance of this technique - it was running suprisingly fast on GeForce 8600GT and extremely fast on Radeon HD 2900

in time when I started using this technique. On current HD6870 (I'm using that now) it runs amazingly fast, and it is also running good on HD5470 in my laptop.

So it might aswell run pretty good in software (especially if sse is used).

If you have any question on how-to or something isn't clear - feel free to ask, I'll discuss details of this technique + I can write some how-to + post shaders I've used, and/or meshes + textures I've used (though they're just grass blades for now).

Is there a way to do this by generating a double plane? What I mean is, duplicate the ground plane and move it up by the length of the grass. Then when a ray hit the top plane, an algo is used to determine what part of the grass is hit. Kind of like refraction in glass, or subsurface scattering. This way, we can have true elevation without creating zillions of poly. I guess the algo must decide (when hitting the top plane) if the ray hit the tip of a grass blade, or the ray continue a little bit more down until it hit a blade, or the ground plane. There is no poly for the grass blades, so the algo would decide where they are. Am I making any sense?

You can also make some good-looking grass by geometry shaders (e.g. generating those zillions of grass run-time from just points "where grass grows"). I'm using a bit different technique and I'll post tomorrow if I'll get some time... for now I'll link to this one:

Or you can render grass using billboards. Check out the article on GPU Gems. There's quite a few grass textures out there you can use that look really nice. Mix it up with some flora to liven it up. For distant lands, I would suggest rendering impostors. You don't have to because many (all?) professional games don't, but I think for such a small feature it could add a lot in return.