Game Development Community

*Massive* amounts of foliage ...

by Melv May · in Torque Game Engine · 08/21/2002 (3:02 am) · 50 replies

I haven't uploaded this yet as I'm doing some testing before I do so but I couldn't resist posting this little image which shows a very efficient algorithm handling *massive* amounts of foliage.

The previous version had a problem in that if you created large quanities of foliage the system would parse each one at render time to see if it was within the visible distance and this potentially added a huge chunk to the frame-time.

Now, new and improved and after many hours of hard-work, I've included a pretty sophisticated quad-tree algorithm to reduce the foliage down to a minimum. I've also orchestrated it such, that you only have a *single* new field to control the culling resolution which makes it easier for non-programmers to use. ;)

Ultimately, the number of billboards you can render comes down to your card so what I'm showing here is not massive quantities of billboards being *rendered* but the *handling* of that huge dataset efficiently.

In the screenshot I setup *one million* foliage items which brought the previous code to it's knees, even on a top-o-the-line computer. Even with this ridiculous number of objects the system performs at over 100 fps.

I've highlighted the FPS, Foliage Items count and the new field which controls the culling resolution. This figure is in world-units and controls the *worst* resolution at which culling takes places. The algorithm will attempt to cull at lower resolutions starting at the whole foliage area and working down to your specified resolution. The higher the culling resolution, the more memory is taken for the quad-tree as it directly controls the recursive pyramid-depth of the tree itself.

The advantage of this algorithm is that it takes into account many factors including a pseudo-volume that I give to the billboards including the sway factors and standard dimensions. It uses this to cull whole areas of billboards that don't fit within the viewing frustum.

It's pretty neat and I will upload it just after I have sent it for testing to a Linux/Mac friend so I am sure it works on all platforms.

Massive Foliage Handling

- Melv.
#21
08/23/2002 (6:01 am)
Sabrecyd,

Thanks, I'm glad you find it useful. Always good to hear about people using my stuff. 8)

Regarding the particle engine, I'm just making sure that I've got a constant stream of work.

... back to the water engine. ;)

- Melv.
#22
08/23/2002 (6:10 am)
LOL
I wasn't going to mention the water, but I was thinking about it :)
#23
08/23/2002 (7:11 am)
Melv -

I've done some experiments with this, wanted to find out if it can do a true forest.

It can. I had 2000 trees of one type, 1000 trees of the other, and 1000 each of two scrub/undergrowth objects, so about 5000 total, with distance 500, so when looking down from the hill there may have been about 4000 visible at once. Still running fine.

Then I went berserk, removed it all and put 100,000 grass foliages in, lighting on, sway on. That gave me about 2 fps. :-)
Playing around I found that 25,000 objects (maybe 20,000 visible at once) is unplayable, but fast enough that I'd say next years hardware will do it. 10,000 seemed to be ok, though I wouldn't recommend it in a game where you have to add other objects, player shapes, etc. as well.

That said, you wouldn't want 100,000 grass billboards there anyway since those at the max distance are little more than a green pixel. On a gras texture background you could probably fade them in at 200 or so instead of the 500 I used.

Very, very impressive. I'm now off playing with invisible shapes (to create pathes through my forest) and other stuff. :-)
#24
08/23/2002 (7:41 am)
Falcon,

Glad you like it. 8)

Trees should be much more usable when I get some mesh work in there.

A combination of the fxShapeReplicator and the fxFoliageReplicator (now allowing objects to be placed on statics) should be able to create fairly convinving jungle or forest scenes.

I might put some screenshots together. 8)

- Melv.
#25
08/31/2002 (9:59 am)
Melv - have you been privy to the dynamic hair generation OGL and Dx8 demos? I think you need to integrate those for doing "real" grass =]

You know what else you need? An option that you can set for each type/class of billboard so that they sway if a player walks into them. (this would be most useful actually, with the "dynamic hairgrass" =]

As soon as I get a working compile I'm going to drop in your foliage replicator and see how it works... I might take a stab (like I'll ever get anywhere) at adding some dynamic grass to the engine.

Thanks for the awesome resources!

Keep up the good work,
Jeff
(PS You guys need to hire melv to work on adding stuff like this to the torque renderer for MONEY... give the poor fellow a job Jeff (Tunnell))
#26
09/10/2002 (8:45 am)
Melv, ever got my email with that bug picture?
#27
09/10/2002 (11:30 am)
Yes Xavier,

I thought I had replied, sorry. To answer your question, yes, I am looking at that particular problem right now. 8)

I will post it up when I've sorted it. Thanks for the heads up.

Cheers,

- Melv.
#28
09/12/2002 (9:59 am)
Melv, Tried out the foliageReplicator. Very, very nice. One issue (don't know if it's on my end or not): I added your grass to a test world and as I rotate my player, the grass will disappear for a few degrees of rotation (approximately toward the southwest looking at the sun). I also added your fxSunlight (located from the SW) but don't yet know if they're related.
#29
09/12/2002 (10:04 am)
Desmond,

Would it be possible for you to send me the settings you've got for the replicator and the approximate position/direction you are standing?

Just checking, when did you last download this? Make sure you've got the latest because that problem was solved (or at least should have been) by the far superior frustum culling algorithm.

- Melv.
#30
09/17/2002 (8:20 pm)
Melv, hopefully you can help.


I installed everything fine with fxFoliage, however, I, for the life of me, cannot get textures onto my foliage. I have double-and-triple-checked name paths, files, etc. in some vain search for the reason as to why I cannot get the darn things to show me anything but qhite boxes.


Any ideas?
#31
09/18/2002 (1:14 am)
Dennis,

If you put it in the standard FPS game then try using "fps/data/water/water" for your foliage texture.

If that doesn't work then you've got other problems.

Let me know.

- Melv.
#32
09/18/2002 (6:42 am)
It didn't work, so I took a version of my code form the day before I put it in and did a clean build.


It worked this time. I probably forgot to copy a semicolon. :D

Thanks, Melv, and keep up the good work!
#33
06/06/2003 (7:10 am)
Melv: is the texture coords correct on the foliage? I noticed that when I use a 256x256 png with the image of the foliage I get one line of pixels from the bottom of my image appearing at the top of the foliage when it is rendered in game. I just shifted the images and its ok with a 1 pixel gap between the foliage and the bottom edge of the image to fix it. Thanks,
Robert
#34
06/06/2003 (11:27 am)
Robert,

That's weired. I'm definately using texture extents 0->1. Perhaps this is a graphics driver issue with the linear interpolation or the clamping.

You could try the following for each...

In "void fxFoliageReplicator::unpackUpdate(NetConnection * con, BitStream * stream)" ...

after the line "mFieldData.mFoliageTexture = TextureHandle( mFieldData.mFoliageFile, MeshTexture );" ...

Add the following...

"mFieldData.mFoliageTexture.setClamp(true);" - This will clamp the texture and stop repeating from edge to edge.

or

"mFieldData.mFoliageTexture.setFilterNearest();" - This will use nearest neighbour interpolation (not as nice and prone to pixelation).

These are the only thing I can think of, short of a driver problem.

- Melv.
#35
06/06/2003 (12:33 pm)
Melv: I am using a Geforce 4 TI 4600 with the latest nvidia drivers. Just shifting the images up by 1 pixel works fine so I will just do that instead of customizing my code to differ from that of the head.

Robert
#36
07/07/2003 (3:10 pm)
Hey Melv,

This kicks mucho ass (but u already know that) but I was curious as to why I cant get clean edges on my grasses? When I have a png w/o feathering at the edges it automagically puts in some what looks like alpha smoothing (but w/ white??). Is there a switch for that? And is the grassReplicator obsolete now?

thanks,

-s
#37
07/08/2003 (7:16 am)
Stephen,

The textures are set to linear intepolation by default. Without this, textures would pixelate close-up. The downside is that the boundary between your texture and the nearest transparent region gets interpolated between when you are close-up so this results in an alpha gradient. This is being done by your graphics hardware.

I placed a field in the replicator that allows you to select the level at which the alpha value is not rendered at all. In OpenGL this is called Alpha-Testing and allows you to clip these regions above a certain level. The problem is that if you don't ,it will actually render a pixel there ( which is transparent or semi-transparent ) and will write into the depth-buffer which will stop other pixels ( which may be valid ) from being rendered. Anyway, this field is called "AlphaCutoff".

I didn't do the grassReplicator, Doyoon Kim did so I'm not sure of its status although I would guess that it has not been worked on as he's been a busy lad on "Tennis Critters".

- Melv.
#38
07/09/2003 (12:56 pm)
Thanks Melv...

Of course I found what the AlphaCutoff did about 20 min later when I went home :) Thanks a lot for this awesome plugin.

-s
#39
07/09/2003 (12:59 pm)
The day and night stuff I did adds dynamic lighting and mission lighting to Melv's fxFoliageReplicator... it may be worth a look/integration/cleanup... it's useful outside of the day night stuff... the grass looks great with rockets flying along, lighting it up. It also looks better not being fully lit on darker missions...

-J
#40
12/09/2004 (11:04 pm)
Hey All, I was really happy to see the fxFoliage in there when I bought TGE thanks!

I keep meaning to post this, not sure if its already been done in head, but I made a small improvement to the foliage code that should let you get a few more fps or add a few more grass blades.

I am working with the 1.3 version

here is the original code
notice that fore every billboard the matrix stack is pushed, we do a full matrix mutiply, we change the model view matrix to be a new matrix, etc... pretty heavy stuff.
//not CLINT_TEST

							// Store our Modelview.
							glPushMatrix();

							// Perform Spherical Billboarding.
							dglMultMatrix(&pFoliageItem->Transform);
							dglGetModelview(&ModelView);
							ModelView.setColumn(0, XRotation);
							ModelView.setColumn(1, YRotation);
							dglLoadMatrix(&ModelView);

							// Fetch Width/Height.
							Width	= pFoliageItem->Width / 2.0f;
							Height	= pFoliageItem->Height;

							// Fetch Flipped Flag.
							LeftTexPos	= pFoliageItem->Flipped ? 1.0f : 0.0f;
							RightTexPos	= 1.0f - LeftTexPos;

							// Draw Billboard.
							glBegin(GL_QUADS);
								// Set Blend Function.
								glColor4f(Luminance,Luminance,Luminance, ItemAlpha);

								// Draw Top part of billboard.
								glTexCoord2f	(LeftTexPos,0);
								glVertex3f		(-Width+SwayOffsetX,SwayOffsetY,Height);
								glTexCoord2f	(RightTexPos,0);
								glVertex3f		(+Width+SwayOffsetX,SwayOffsetY,Height);

								// Set Ground Blend.
								if (mFieldData.mGroundAlpha < 1.0f) glColor4f(Luminance, Luminance, Luminance, mFieldData.mGroundAlpha < ItemAlpha ? mFieldData.mGroundAlpha : ItemAlpha);

								// Draw bottom part of billboard.
								glTexCoord2f	(RightTexPos,1);
								glVertex3f		(+Width,0,0);
								glTexCoord2f	(LeftTexPos,1);
								glVertex3f		(-Width,0,0);
							glEnd();

							// Restore our Modelview.
							glPopMatrix();


see next post