Sign in to follow this  
bzroom

Sorting intersecting grass quads

Recommended Posts

I was reading this article on grass rendering: http://http.developer.nvidia.com/GPUGems/gpugems_ch07.html It describes clusters of 3 quads, in a star shape, to render patches of grass. It mentions that they must be sorted. But i'm confused how you'd go about sorting the 3 quads, since they intersect. It seems like they'd need to be clipped and split. Or is it refering to just sorting the clusters, as a whole, as a "good enough" aproximation? Thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by rouncED
If you get your grassy meadows going, id love to see it. :)
My eyes popped out when I saw that screen shot.


It's pretty much how Bethesda handled grass for Oblivion.

Share this post


Link to post
Share on other sites
It seems wrong though, to sort only the clusters. If you had only 1 cluster, odds are it will look entirely wrong. It's only if it's surrounded by clusters does it have a chance of looking decent without proper sorting.

While that's an extreme case, consider the clusters along the edge of a tall grassy section. I imagine they'ed be self overdrawn with invisibleness in lots of the cases.

I won't know till I try it and i'll be sure to post the results.

Also is there a special trick to sorting billboards, or specifically close-up billboards. While ultimately i shouldn't be so dern close to a cylindrical billboard, temporarily i am. When I sort them based on distance to the camera, I get weird issues when close up and rotating, sometimes it seems that the closer ones are drawn first.

Maybe since it's cylindrical i need to look at the distance in only the horizontal plane, it might have been my camera height that was causing issues now that i think about it. Even though it was only a small value. Does that make any sense?

Share this post


Link to post
Share on other sites
Hey, I've been playing around with rendering grass like that article says, only I'm trying to implement a fast non-programmable-pipelines version (because my netbook is fun like that) using standard OpenGL calls.. I think that the farthest I'll push my project is multitexturing..

and I'll say that I am using the alternative of alpha testing, instead of blending, and thus have eliminated the need to sort my grass. I just lump them all into a static set per terrain-mesh (which is divided into 16x16 units) and draw them that way. I also don't use quads to draw them, I use a triangle that is twice the dimensions of an equal quad..

eg: mspaint was less painful to articulate:

http://www.van-noland.com/img/triangle_for_quad.jpg

Although I've yet to figure out if the alpha-testing on a bigger polygon is worse than 2 smaller polygons (a quad).. So far, alpha testing itself doesn't seem to make any difference on framerate, so, I imagine, that if anything, using one triangle instead of a quad for a grass polygon is better.

I had to tweak my alpha-testing value so that the grass doesn't get blocky the further it is, or get 'thin' as the mipmaps come into play..


EDIT: Oh yea, don't forget to set GL_TEXTURE_WRAP_S and WRAP_T to GL_CLAMP, because GL_REPEAT is all bad for using triangles in place of quads.

Share this post


Link to post
Share on other sites
what you can do is alpha_to_coverage
see ARB_multisample

this will look a bit better than plain alphatest

Share this post


Link to post
Share on other sites
i'd love to see the results too, bzroom!

btw does anyone know some common techniques to place grass dynamically on terrain in realtime?

Share this post


Link to post
Share on other sites
Quote:
Original post by Daniel E
i'd love to see the results too, bzroom!

btw does anyone know some common techniques to place grass dynamically on terrain in realtime?


You mean procedurally generate positioning for the grass? Please elaborate, if you can.

Share this post


Link to post
Share on other sites
Quote:
Original post by radioteeth
You mean procedurally generate positioning for the grass? Please elaborate, if you can.


yes, exactly. i want to save as little data as possible but the grass positions should be persistant. i thought about something like passing a heightmap to the shader and sample it for the y coordinate.

Share this post


Link to post
Share on other sites
you just need a psuedo random generator. then wether you keep around the chosen data points or recompute them again later doesnt matter. just reseed your generator, could be seeded with a height map, could be done in shader.

Share this post


Link to post
Share on other sites
Quote:
Original post by rouncED

My eyes popped out when I saw that screen shot.


Another interesting point - that Codecreatures Benchmark was released in 2002 and uses DX 8.

Share this post


Link to post
Share on other sites
Quote:
Original post by bzroom
you just need a psuedo random generator. then wether you keep around the chosen data points or recompute them again later doesnt matter. just reseed your generator, could be seeded with a height map, could be done in shader.

yes thats what I do, wg something like

camera has entered a new grass block

srand( camX * XXX + camZ );
loop all grass, creating at random positions but because of srand they will be in the same positions on the map

Share this post


Link to post
Share on other sites
i have no idea how to apply the new random positions to the quads though. locking and changing the vertex buffer is too slow isnt it?

what i got now is this grid of the same repeating grass cluster that adds and discards cells based on the camera position



i cant figure out how to change the quad positions within each cluster or how to look up the corresponding height values from a heightmap in the shader though.

Share this post


Link to post
Share on other sites
You'd need a vertex texture fetch to do it in shader.

And you can certainly update your vertex buffer, it's not too slow. You should be able to just send the new data over, overwriting the exiting data. If you try to read back the buffer and then modify it, it may be slow. But given the right storage mode you'll be alright.

Share this post


Link to post
Share on other sites
So i got this working. (Video)

But my biggest worry is that i refill the buffer for each cell in each frame...


while(j < cells)
{
i = 0;

while(i < cells)
{
vertexbuffer->Lock( 0, locksize, (void**)&pVertices, 0 );
memcpy( pVertices, vertices[i][j], locksize );
vertexbuffer->Unlock();

...

renderBillboards(patch_pos_x, patch_pos_z, 0);

i++;
}

j++;
}




Is this the way to go or is this approach wrong?

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