Sign in to follow this  
Dragon_Strike

grass shadows

Recommended Posts

im working with some grass rendering.. im rendering the grass using billboards... as described in gpu gems.. for lighting i use the terrain normal at the grass position and then i use the billboards texture normal and mix these to together for a "grass normal"... but how would i go for shadows? i need a way that each grass texture will cast shadows on both terrain and other grass textures...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Don't use billboards for grass. Create little models, animate them to make them look like they're in a wind. Don't make them turn towards the camera and all your problems will be solved. Then just shadowmap them :)

This is how most games do it these days.

Share this post


Link to post
Share on other sites
In such an application, shadow volumes are almost completely out of the questions, so shadow maps are going to be your only option.

Note that with shadow maps you can use alpha testing (and alpha blending with variance shadow maps), so you can continue to use sprites, although you need to consider how they are going to work from the light's point of view.

Depending on the complexity of your grass, you may want to consider a probabilistic representation, such as Deep Shadow Maps, or variance shadow maps. It might turn out to be easier and better-looking to represent your field of grass as a probability distribution rather than individual objects. However if you still want to see the nice shadows of individual grass strands, you're going to be hard-pressed to make that work real-time as the number of strands grows...

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Don't use billboards for grass. Create little models, animate them to make them look like they're in a wind. Don't make them turn towards the camera and all your problems will be solved. Then just shadowmap them :)

This is how most games do it these days.


would small models take alot of perofrmance? my demo right now si pretty slow.. but i dont know if its the geometry or the fragment sahder thats taking the performance

Share this post


Link to post
Share on other sites
Quote:
Original post by AndyTX
In such an application, shadow volumes are almost completely out of the questions, so shadow maps are going to be your only option.

Note that with shadow maps you can use alpha testing (and alpha blending with variance shadow maps), so you can continue to use sprites, although you need to consider how they are going to work from the light's point of view.

Depending on the complexity of your grass, you may want to consider a probabilistic representation, such as Deep Shadow Maps, or variance shadow maps. It might turn out to be easier and better-looking to represent your field of grass as a probability distribution rather than individual objects. However if you still want to see the nice shadows of individual grass strands, you're going to be hard-pressed to make that work real-time as the number of strands grows...


as far as ive understood u have to render the sceen 2 times wth shadow mapping... which cuts the performance by half...

ive was thinking for som kind of parallel texture projection using a black version of teh grass being shadeds texture?

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Don't use billboards for grass. Create little models, animate them to make them look like they're in a wind. Don't make them turn towards the camera and all your problems will be solved. Then just shadowmap them :)

This is how most games do it these days.


Dont animate grass models whatever you do, use a vertex shader to animate, otherwise performance will divebomb.

Otherwise you can do grass in whatever way you want, some games use models, some use sprites, but they key is batching/instancing.

You must use batches and or instancing to do large number of grass. If properly implemented, you can then render it reasonably cheaply, and also you can get away with shadow maps.

In this case, you can use models, or batched sprites (not all sprites have to face the camera, you can make "X" crosses out of two sprites).

Although having each grass model cast its own shadow is going to be costly no matter what. I would reccomemend that each grass recieves sahdows fomr otehr thigs and terrain, but doesnt cast its own sahdow. If it does have to , maybe you can update the shadow map less frequently.



Share this post


Link to post
Share on other sites
Quote:
Original post by Dragon_Strike
but how do i overcome the problem with the depthmaps resoltuin? a 4096x4096 res wont give very good results since i have a prety large sceen...

If you're only interested in projection onto a relatively-planar ground, it's actually possible to find a projection matrix that will map pixels perfectly onto a "plane of interest". This will give you ideal resolution on this one plane, so if your ground is "planar enough", you'll be fine.

Otherwise you'll have to split up your shadow map using something Cascaded Shadow Maps, or similar.

You have to realize that wanting shadows of individual grass strands is going to cost quite a bit regardless of how you implement it... there's no silver bullet for light transport - you're always trading off speed and quality of approximation.

Share this post


Link to post
Share on other sites
for good quality you have to use some form of CSM and only in your nearest shadow map you need to render the grass. The rest you won't see anyway. And up close I render my grass as instanced geometries, and a little bit further I render billboarded patches. You don't see the transition and get the idea the whole field is field with realistic grass geometries. Shadow on and from grass is very expensive because they increase your fillrate with a lot because of the big amount of overdraw .. Might be better to try to fake it with precomputed shadow maps or something which you can tile. This technique works fine for tree shadows in a forest so I presume it must also work for grass patches.

Good luck,
Kenzo

Share this post


Link to post
Share on other sites
correcting a couple of errors here
A/ use billboards for the grass
B/ with shadowmaps this will give wrong results thus u have to have billboards for the lights viewpoint as well
C/ use GL_SAMPLE_ALPHA_TO_COVERAGE for the best quality looking grass
D/ pesonally im of the opionion the best results (quality vs speed) are grass recieves shadow but doesnt cast them

Share this post


Link to post
Share on other sites
havent read the whole post but gpu gems 2 has great grass shadow trick in first article. however its to cast shadows onto the grass. you take 3 points on the billboard left middle right and see if they ar within the shadows of other objects, then you see of the 3 points how many are in shadow and then adjust accordingly this does a nice soft shadow from surrounding objects might help some. The university of central florida has http://www.irisa.fr/siames/GENS/kboulang/publications/grassSiggraph2006ppt.pdf

thats a pretty good algorithm and i expect to see it in upcoming football games as they said ea supported them with it

Share this post


Link to post
Share on other sites
taking pictures of grass works fine. Then modify them with photoshop.
The problem with the GPU gem article is that it's for static lights else you have to recompute them every time the light changes. When you a SPU left you might be able to do this but else .. :)

This PDF looks indeed very nice but I wonder how many triangles you have to draw to make a normal piece of terrain look realistic. A few 100K I presume. And vertex and pixel shaders are not cheap either I think (with wind movement and heightmaps that is it).

Regards,
Kenzo

Share this post


Link to post
Share on other sites
Quote:
Original post by yoshscout
havent read the whole post but gpu gems 2 has great grass shadow trick in first article. however its to cast shadows onto the grass. you take 3 points on the billboard left middle right and see if they ar within the shadows of other objects, then you see of the 3 points how many are in shadow and then adjust accordingly this does a nice soft shadow from surrounding objects might help some. The university of central florida has http://www.irisa.fr/siames/GENS/kboulang/publications/grassSiggraph2006ppt.pdf

thats a pretty good algorithm and i expect to see it in upcoming football games as they said ea supported them with it


ive looked at that paper and tried to implement the model part... basicly i create 32x32 blocks in which i generate grass depending on a density map...

im storing each grass blade in a displaylist for performance.. but if im gonna store every blade in memory it would take massive amounts of memory.. how do i solve this?

Share this post


Link to post
Share on other sites
I will try to answer some of your questions. I am the one who wrote the article for Siggraph.

I worked one year and a half on grass rendering and encountered many of your problems, particularly about performance.

In my approach, I use geometry for blades of grass in the foreground. I create patches of about 3000 grass blades. Since each grass blade is defined by a triangle strip, I do not use display lists for each grass blade, it is too expensive. I use a vertex buffer object for the whole patch of grass, I render it with a single display list, but I use the GL_EXT_multi_draw_arrays extension to make a single draw call for the 3000 triangle strips (this last extension multiplied the rendering speed by 4.5).

For grass that is farther, I do not use billboards, but a kind of volume rendering instead, based on slices. This allowed me to get very smooth transitions, and very good parallax effect (3D effect).

Quote:
but how would i go for shadows? i need a way that each grass texture will cast shadows on both terrain and other grass textures...


For the shadows, I found a way to obtain approximative but very convincing soft shadows cast by grass blades to other blades. It is described in my technical report . To summarize, I use a cylindrical shadow mask around each blade of grass. This shadow mask is unique (here is the approximation), and rotated for each blade of grass to hide the fact that they are not real shadows. Here the kind of result I get:

Shadows cast on grass blades

I really encourage you to not use shadow maps. The resolution you need has to be very high, you have an additional render pass, you cannot use billboards with them.

To cast shadows on the ground, I use regular projected shadows on a plane. The use of stencil buffer removes the bugs due to overdraw. However, it has some performance impact. Recently, someone proposed me to use framebuffer objects rather than stencil buffer. I did not implement it yet, but I think it would be useful. Also, to cast shadows on curved terrains, I compute the projection matrix in the vertex shader rather than in the CPU, by considering that the terrain is locally flat compared to the size of a grass blade. I just give the normal of the terrain for each vertex I am processing. It looks expensive, but it is not really since the bottleneck was in another stage of the pipeline in my case.

Quote:
im storing each grass blade in a displaylist for performance.. but if im gonna store every blade in memory it would take massive amounts of memory.. how do i solve this?


I use patches of 3000 grass blades and make use of instancing. A single patch is stored in memory, so it costs almost nothing. However, if I render grass patches over a uniform grid, repetition is visible, that is why I assign a random symmetry to each patch (stored in a map covering the terrain).

Quote:
This PDF looks indeed very nice but I wonder how many triangles you have to draw to make a normal piece of terrain look realistic. A few 100K I presume. And vertex and pixel shaders are not cheap either I think (with wind movement and heightmaps that is it).


I use 8 triangles per grass blade, about 3000 grass blades per patch, so about 24K triangles per patch. Depending on the view angle, I have 0 to about 10 patches rendered per frame (the others are rendered with volume rendering). Roughly, I have about 100K triangles rendered per frame. However, with the VBOs and the multi draw array extension, I get really interesting performance. The proof is this image:

Park scene

rendered interactively (11 to 50 fps on a GeForce 7 depending on the view angle, at height of a human viewer) at a correct resolution with high antialiasing, anisotropic filtering, and high texture resolution. Also, the trees represent 600K alpha-blended polygons. The bottleneck was not coming from the geometric grass blades. The size of the terrain has almost no influence, because the rendering of far grass is very cheap. I rendered a football field of 627 million virtual grass blades at 60fps (250fps from a TV camera).

You can have more information on my webpage.

Share this post


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

In my approach, I use geometry for blades of grass in the foreground. I create patches of about 3000 grass blades. Since each grass blade is defined by a triangle strip, I do not use display lists for each grass blade, it is too expensive. I use a vertex buffer object for the whole patch of grass, I render it with a single display list, but I use the GL_EXT_multi_draw_arrays extension to make a single draw call for the 3000 triangle strips (this last extension multiplied the rendering speed by 4.5).


i think i formulated my self wrong before.. i use a single display list for all teh grass blades in a patch... i do not quite uunderstand how u use GL_EXT_multi_draw_arrays if u store a patch in a buffer.. wouldnt the entire patch be drawn with only 1 call?

if ive understood correctly u only create 1 grass patch and then use the vertex buffer to displace all the grass patches to their correct position... but could u explain in more detail how u create asymmetry and also how u remove blades based on the density map.. does the vertex buffer have afunction for skipping vertexes or similar?

[qoute]

For grass that is farther, I do not use billboards, but a kind of volume rendering instead, based on slices. This allowed me to get very smooth transitions, and very good parallax effect (3D effect).

[/quote]

how do u generate these slices? do u use a single prestored texture or do u create it in a precomupting state when rendering the real grass blades from the side and storing the results in a texture?


Quote:
but how would i go for shadows? i need a way that each grass texture will cast shadows on both terrain and other grass textures...

For the shadows, I found a way to obtain approximative but very convincing soft shadows cast by grass blades to other blades. It is described in my. To summarize, I use a cylindrical shadow mask around each blade of grass. This shadow mask is unique (here is the approximation), and rotated for each blade of grass to hide the fact that they are not real shadows. Here the kind of result I get:



ive been trying with a similar approach but instead of a cylinder i use a singe plane faceing the sun.. since my sun is always on one side of th grass... but my issue is how i generate the shadow mask?

Quote:

I really encourage you to not use shadow maps. The resolution you need has to be very high, you have an additional render pass, you cannot use billboards with them.

To cast shadows on the ground, I use regular projected shadows on a plane. The use of stencil buffer removes the bugs due to overdraw. However, it has some performance impact. Recently, someone proposed me to use framebuffer objects rather than stencil buffer. I did not implement it yet, but I think it would be useful. Also, to cast shadows on curved terrains, I compute the projection matrix in the vertex shader rather than in the CPU, by considering that the terrain is locally flat compared to the size of a grass blade. I just give the normal of the terrain for each vertex I am processing. It looks expensive, but it is not really since the bottleneck was in another stage of the pipeline in my case.

i dont understand qutie how this work.. ill just have to do some more readin


Quote:
im storing each grass blade in a displaylist for performance.. but if im gonna store every blade in memory it would take massive amounts of memory.. how do i solve this?

I use patches of 3000 grass blades and make use of instancing. A single patch is stored in memory, so it costs almost nothing. However, if I render grass patches over a uniform grid, repetition is visible, that is why I assign a random symmetry to each patch (stored in a map covering the terrain).


as before.. how do u create the asymmetry? do u use this random seed to move teh grassblades in a random direction in the vertex buffer after uve move the entire patch?


Quote:
This PDF looks indeed very nice but I wonder how many triangles you have to draw to make a normal piece of terrain look realistic. A few 100K I presume. And vertex and pixel shaders are not cheap either I think (with wind movement and heightmaps that is it).

I use 8 triangles per grass blade, about 3000 grass blades per patch, so about 24K triangles per patch. Depending on the view angle, I have 0 to about 10 patches rendered per frame (the others are rendered with volume rendering). Roughly, I have about 100K triangles rendered per frame. However, with the VBOs and the multi draw array extension, I get really interesting performance. The proof is this image:

rendered interactively (11 to 50 fps on a GeForce 7 depending on the view angle, at height of a human viewer) at a correct resolution with high antialiasing, anisotropic filtering, and high texture resolution. Also, the trees represent 600K alpha-blended polygons. The bottleneck was not coming from the geometric grass blades. The size of the terrain has almost no influence, because the rendering of far grass is very cheap. I rendered a football field of 627 million virtual grass blades at 60fps (250fps from a TV camera).

You can have more information on my webpage.

[/quote]

as another point i cant use VBOs for some reason my coputer crashes.. which is why im forced to use DL..

anyways thanks for answering my previous questions!

Share this post


Link to post
Share on other sites
also do u use any kind of diffuse lighting?

ive been experimenting with defining normals for each vertex and then bending them towards the camera during rendering.. this way i get both lighting and self-shadowing... but im not sure if its rly necessary...

Share this post


Link to post
Share on other sites
Quote:
i think i formulated my self wrong before.. i use a single display list for all teh grass blades in a patch... i do not quite uunderstand how u use GL_EXT_multi_draw_arrays if u store a patch in a buffer.. wouldnt the entire patch be drawn with only 1 call?


I render each blade of grass with a triangle strip, so I cannot use one single draw call since I have to restart the primitive for each triangle strip. I could use degenerate triangles but I used a simpler approach. In OpenGL, I use glDrawArrays() to render one triangle strip (not glDrawElements since each vertex is processed only once), and I would need to call this function for each grass blade. However, with the GL_EXT_multi_draw_arrays extension, I give an array of arrays to render, reducing the patch rendering call to one glMultiDrawArrays() (about 4.5x speed-up). I am using VBOs at the same time (about 2x speed-up), and embed the rendring call in a display list (about 1.2x speed-up). The total speed-up is about 10x compared to traditional vertex arrays.

Quote:
if ive understood correctly u only create 1 grass patch and then use the vertex buffer to displace all the grass patches to their correct position... but could u explain in more detail how u create asymmetry and also how u remove blades based on the density map.. does the vertex buffer have afunction for skipping vertexes or similar?


I displace each patch using a translation vector passed as an uniform variable in OpenGL Shading Language. For the orientation, it works like this:
- for geometric grass patches and vertical slices, I mirror them using an asymmetry vector, (-1,-1), (-1,1), (1,-1) or (1,1) passed as a uniform variable to the vertex shader. It is OK for these two types of patches since they are rendered individually
- for horizontal slices (faraway grass), I render them as macro-cells. I cover several cells of the terrain uniform grid with a single quadrilateral on which the texture is repeated. The problem is the management of the orientation. Hence I cover the terrain with an orientation map, where each texel corresponds to a patch of the terrain. This texture is not filtered (GL_NEAREST filter). The red and green channels give the asymmetry vector per rendered fragment, and for each fragment I multiply the current texture coordinates by this asymmetry vector. A modulo 1 gives me values for texture coordinates in [0,1).

You can have details in Section 4.1 of the technical report.

Quote:
how do u generate these slices? do u use a single prestored texture or do u create it in a precomupting state when rendering the real grass blades from the side and storing the results in a texture?


Detailed in Section 3.3 of the technical report. To summarize, I render slices of a patch defined by geometry (between two clipping planes) for several view and light angles. I store this information in files (for faster loading of the application) under the form of a texture atlas for each slice. At rendering time, to render a given slice, I combine several images taken from the texture atlas to create the final fragments. I do this because the grass I am rendering is fully dynamically per-pixel lit. The program would run a lot faster without, but since I am doing researches, I am always working with the worst case.

Quote:
ive been trying with a similar approach but instead of a cylinder i use a singe plane faceing the sun.. since my sun is always on one side of th grass... but my issue is how i generate the shadow mask?


Since the shadow mask approach is an approximation, you can use an approximation to create the shadow mask ! In my case, I render a slice of a patch of grass with geometry in black and white, seen from the side.

Quote:
Viny, it looks awesome! DEMO PLEASE!!!


Thank you [smile]
On my webpage, in the downloads section, you can get a video of the demo (I advise to get the high resolution one if you can). For a live application, I did not release it yet because it uses a 3D engine I am developing that is still experimental. I have no guarantee it will work correctly on every computer. I am working on it.

Quote:
also do u use any kind of diffuse lighting?

For the current version, I am using simple diffuse lighting without specular. I am searching for a better representation of the grass blades defined with slices to have this additional light component.

Quote:
ive been experimenting with defining normals for each vertex and then bending them towards the camera during rendering.. this way i get both lighting and self-shadowing... but im not sure if its rly necessary...


I am sorry, I do not understand. How do you get self-shadowing by bending the normals ?

Share this post


Link to post
Share on other sites
Quote:
Original post by Viny
Quote:
ive been experimenting with defining normals for each vertex and then bending them towards the camera during rendering.. this way i get both lighting and self-shadowing... but im not sure if its rly necessary...


I am sorry, I do not understand. How do you get self-shadowing by bending the normals ?


since i render one strip for both faces of the blade i can only define normals for one of the grass faces... but since the camera is always facing just one of the faces i simply invert the normals so that they face the camera and calculate the blades lighting based on that... and the blades where this transition occurs i only bend the normals instead of inverting them so that i get a smooth transition... i dont know if this is physically correct but it looks not all that bad...

Share this post


Link to post
Share on other sites
Quote:
since i render one strip for both faces of the blade i can only define normals for one of the grass faces... but since the camera is always facing just one of the faces i simply invert the normals so that they face the camera and calculate the blades lighting based on that... and the blades where this transition occurs i only bend the normals instead of inverting them so that i get a smooth transition... i dont know if this is physically correct but it looks not all that bad...


Your problem is typically a two-sided lighting situation. It happened to me also. The transition between front and back face was really bad. I did not think about bending the normal, nice idea by the way. However, what I did was to invert the normal in the fragment shader and compute lighting in the fragment shader also. It is diffuse lighting, so per-pixel lighting looks useless, but the bottleneck of grass rendered with geometry is vertex processing, so putting this computation in the fragment shader increases the global speed. I got some speed-up like that, and also the two-sided lighting was perfect since computed per fragment.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Viny, would you technique work with taller types of grasses too: http://www.wildnatureimages.com/3000%20to%2010000/C6CT9332..jpg ?

Share this post


Link to post
Share on other sites
I successfully rendered 10 inch high grass (25cm) with animation. The volume rendering part works pretty well for longer grass. For animation, a linear distortion is used so may not be suited for very long grass. I did not test a lot the animation part, I did researches more on the lighting and the levels of detail management.

Share this post


Link to post
Share on other sites
im just wondering how u get the bended shape on the grass? do u have preset coordinates or do u use some kind of function which uses a random value?

ive been workin with a random value quadfunction but i cant seem to get it natural...

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