6
\$\begingroup\$

I see a number of tutorials on how to create good looking grasses when creating 3D renders but can't think how to model it for realtime/use in a game's scenery.

Sure simple models with alpha cutouts can be used to create plants and trees in really awesome scenery but what about a lawn?

Are there any good tricks to achieve this effect? I tried with a simple 4 sided box and a small texture and the number of objects needed for a decent appearance made Max crawl to a halt.

(I am thinking it may be possible with a shader but that is a whole other area so thought I would just ask about anyones experience with modelling it here)

Thanks!

\$\endgroup\$
2
  • \$\begingroup\$ Max uses a ray-tracer. You won't need that kind of quality for in-game use. \$\endgroup\$
    – DeadMG
    Commented Feb 28, 2011 at 18:32
  • 1
    \$\begingroup\$ @DeadMG that kind of quality is possible in realtime, using grass constructed on geometry shader and shaded with some opacity map technique. \$\endgroup\$
    – Notabene
    Commented Feb 28, 2011 at 18:54

3 Answers 3

4
\$\begingroup\$

I'm not sure what is considered the best approach, but one option would be to use instanced geometry - you provide the GPU with a 3d model and a list of places/orientations where you'd like it drawn (preferable in the form of a concatenated matrix), and the GPU will handle the rest via a custom vertex shader.

Basically, you create two vertex buffers: one containing your 3D model (a blade of grass or patch of sod, for instance), and one containing a list of transformation matrices, each matrix containing the scale+rotation+translation where you'd like to render an instance of your model. (You'll need a custom vertex structure to hold the matrix - it's a vertex buffer in name only, and is just used to pass matrices to the GPU.)

Then, you'll need a custom shader. The vertex shader will get called for each vertex in each stream, so for each call you'll get two input parameters: one vertex from your blade model, and one of the transformation matrices. The shader then transforms the model vertex with the matrix, and returns the updated position.

If you want effects like wind, etc, you can adjust the matrix for each instance and update the matrix stream.

Using a model for a patch of grass rather than individual blades is makes it easier to cull. If you're using an octree or BSP for collision and visibility determination, you can reduce the depth of your tree by dealing with larger "blocks" of grass instead of smaller blades. Also, it's easy to provide a less complex/less-detailed model for a patch of grass if you detect a performance issue.

There's also something called a "Geometry Shader" that may apply here, but I don't know anything about it other than it's relatively new and apparently (?) not supported on the xbox.

Here's a link to an XNA instancing sample.

Update

Alternate methods: Though rendering lots of grass via instancing is significantly faster than other geometry-based methods, it can still be very expensive. GPU Gems contains an interesting alternative using intersecting billboard clusters.

And, of course, there's shell rendering, which consists of rendering a stack of textured polys, each with a map of "dots" on a transparent background. Each texture has an image of a cross section of a patch of grass - think dots on a transparent background. When you render them in close proximity, the solid parts of the texture appear to be extruded and connected between the layers. Not sure how well this performs.

Update 2

I hadn't noticed that the XNA billboard sample is a grass simulation.

\$\endgroup\$
3
  • \$\begingroup\$ Geometry shader is not new. It was the biggest feature of shader model 4. And now we have shader model 5. Geometry shaders are truly not supported on the XBOX, because it has SM3. But where did sebf specify that he uses xna or xbox? :] \$\endgroup\$
    – Notabene
    Commented Feb 28, 2011 at 17:51
  • \$\begingroup\$ @notabene: His link is to 360 scenery. \$\endgroup\$
    – DeadMG
    Commented Feb 28, 2011 at 18:33
  • \$\begingroup\$ Thank you for the detailed explanation of instanced geometry and the sample; I will look forward to trying this. This looks the best method for 'modelled grasses' as I mean them here. It will be interesting to read up on geometry shaders and how they can be used with this. \$\endgroup\$
    – sebf
    Commented Mar 1, 2011 at 0:02
6
\$\begingroup\$

The probably best reference to rendering grass: Boulanger.

Also, since geometry shader was mentioned: this techdemo has slightly inferior quality compared to K. Boulanger's technique, but it is stunning in another way since it draws crazy amounts of grass blades and does the culling via the geometry shader and transform feedback, which is a pretty cool idea.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for those demos, the results of both look excellent. I will be rereading the Instance Culling article a couple of times as this seems a very interesting implementation and I am not familiar with this pipeline stage. \$\endgroup\$
    – sebf
    Commented Mar 1, 2011 at 0:08
1
\$\begingroup\$

i would LOVE to suggest pure geometry shader based solution, but you dont know even basic vertex-fragment shaders. So no, let's stay on the ground:). I will only guide to this site:

Loopix project

It is great place where to grab simple vegetation models. They are very lowpoly and always only one textured, with very smart texture repeating.

Use instanced rendering for sure.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the link! Though I am familiar with vertex shaders ;) what I meant in the question was to keep discussion to modelling (i.e. design time based) solutions as opposed to a shader based solution which I would have asked about in a seperate question, though it seems from the answers the consensus is very clear :D. Do you have a link to an example of a pure shader solution as it would be interesting to compare it with the instanced geometry solution? \$\endgroup\$
    – sebf
    Commented Feb 28, 2011 at 23:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .