Sign in to follow this  
AdamGL

Grass

Recommended Posts

I'm making a 3d-Sidescroller with the terrain being tilted towards the viewer at a 35 degree angle. For the terrain, I'm making grass rendered pixel by pixel. I loop a rand() function to get different locations of the grass, each time rendering a grass of blade. I do this for 700 blades of grass. The grass itself is rendered through a loop of GL_POINTS using glVertex3f() to draw the individual points making up the blade. I am obviously doing something wrong because my frame rate is low. I'm using an ATI RADEON 9800 pro.(By frame rate being slow, I mean that when my mouse goes over the X or [] or - signs in the window, they illuminate quite slowly. This is my only indication for I haven't made an fps counter yet)

Share this post


Link to post
Share on other sites
Eww, yeah, there's no reason to use points. The best method, IMO, is to use textured quads with alpha testing for most kinds of low-detail plant growth, and basically billboard them - here's a lousy shot of something I wrote a couple years ago -



(Shot with different (sucky) alpha settings with the grass a little bit more ordered (not random))

Heck, even using lines isn't bad, though its a heck of a lot more performance-intensive. Each line counts as a polygon, and covers a lot less area than a quad, so you have to use more of them to get the same effect -



Likewise, you'd have to use a heck of a lot more points (and thus more primitives) to get the same effect with GL_POINTS, which results in a slowdown. So I'd suggest going with the "find a good verticle grass texture and draw a bunch of quads on the screen" approach more than anything else, simply because (by my flawless logic) its the most efficient.

And no, I have no idea where people get those nice-looking textures from :/

EDIT: As a side note, if your grass is static you should not be generating it every pass. This will lead to extreme performance degradation since that's a heck of a lot of computation for large amounts of grass. Instead, you should put all of the grass geometry into a vertex buffer object (VBO) and render that (or even just a display list, if my memory serves me correctly). You should see a considerable performance gain, especially if you were previously rendering in immediate mode before (ie, glBegin(), glEnd() blocks).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i suggest you to use vertex arrays. or - even better - Vertex Buffer Objects (VBO)
calling vertex3f for every point is the whorst approach you can do. with vertex arrays you speficiy an array of points with a single function-call, and then you draw them all at once using a single call.
i suggest you, to look at the vertex array spec in the opengl specification (or just google for it, there are a lot of tutorials and sample apps about this topic.)
you will notice an incredibly huge performance improvement.
then move on to the VBO extension (again: just google for it, or take a look at the ATI/NVIDIA sdk's. you can get them in the public developer-sections of the companys websites) and you will expirience even bigger performance improvement. especially, when you are using static geometry.
(btw. the vertex arrays are also very good for drawing anything else in your demo: scroller, and especially the terrain)

and for further optimizations: try to do as less drawcalls as possible.
sort your objects by textures and put as many as possible of them into the same vertexarray to draw them with a single call.
every change of a texture slows you down, so putting thing which could be otherwise drawn with one call, into one, single texture... but i think, i am going too far.

so anyway, for now just take a look at vertex arrays and your problem will be solved.

Share this post


Link to post
Share on other sites
Okay, I see what you guys are saying, but I refuse to use the textured quads idea(I don't know why). So scrap the GL_POINTS, use vertex arrays and use triangles? I want to make the blades bend too. Triangles won't do that for me...

Share this post


Link to post
Share on other sites
Quote:
Original post by AdamGL
Okay, I see what you guys are saying, but I refuse to use the textured quads idea(I don't know why). So scrap the GL_POINTS, use vertex arrays and use triangles? I want to make the blades bend too. Triangles won't do that for me...

I'd recommend the use of VBO's over vertex arrays if your grass is not going to be animated. The reason for this is that when you render a vertex array, the vertex data is streamed over to the GPU, which is something that can be avoided if the data doesn't change each pass. A VBO stores the data in GPU memory, meaning no streaming each pass. The drawback is making major changes to VBO geometry (ie, changing the bend in every blade of grass) can make it less effective because you have to send data anyway.

So, if you're going to animate your grass, you might want to use a vertex array. If you are not going to animate it, then you will want to use a VBO.

As for the bending - I remember reading an excellent paper on real-time rendering of windblown prairie grass with seamless LOD-changes, but I can't find it anywhere... I wish I still had a copy.

In any case, you can achieve the bending effect with either single blades of grass or textured quads by using multiple triangles -



Above is a picture showing how a single blade can be composed of multiple primitives, and still achieve a dynamic bend. You can use some maths to determine the curvature of the blade, depending on how "advanced" you wanted to make it. I suck at math, so if I tried something like this, I'd probably end up using some trig identities and just using an angle to represent bend, and not try to figure out curvature.

This can also be extended to be used on entire textured quads for low LOD areas -



Again, by adjusting the coordinates we can make it appear that the set of blades represented by the quad is bending. The problem with this is that it doesn't look good up close, because all the blades move at the same time. For a low LOD, however, you can't tell the difference because a whole bunch of little blades will be swimming around at varying rates and it looks nice.

But yeah. I'm not a real fan of the untextured approach. And at the same time, I've seen some really poorly-done textured ones too. Personally, I think the trick is to find really nice-looking textures, but I both suck at making and finding them, unfortunately [sad]

Share this post


Link to post
Share on other sites
Much less expensive than rendering points for a blade. As for performance, what can I say? Its three times as expensive as using a single triangle for a blade :P

(and actually, there are 5 triangles in the blade pictured above. 2 for each of the lower quads, 1 for the top one :])

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this