BlitzForest/Grass - Dense trees & grass rendering

Blitz3D Forums/Blitz3D Programming/BlitzForest/Grass - Dense trees & grass rendering

John J.(Posted 2007) [#1]
Note: This is two of several libraries that have been sitting on my hard drive for about a year not being used (since I have moved on to my own C++ game engine [using Ogre]). I have decided to release a few of these libraries since can be very useful to many of you, I'm sure.


Download BlitzForest & BlitzGrass Here





BlitzForest Library:
BlitzForest enables you to place thousands, and literally tens of thousands of trees in your game with little performance penalty. Using 30 thousand, or even 50 thousand trees would not be too much for BlitzForest to handle. Even old video cards will be able to render up to 50,000 trees at relatively smooth frame rates. BlitzForest's only limitation is the required use of prop-style trees.

BlitzForest uses a complex optimization method, taking full advantage of minimal-surface renders, LOD optimization, batch loading and reprocessing, and occlusion.

What makes BlitzForrest so useful is not only it's features, but the fact that all these complex operations are done automatically! All you have to worry about is using the very simple commands of BlitzForrest, such as BF_PositionTree() and BF_LoadTree().

Even though initialization of BlitzForrest and LOD settings is easy, this is probably as hard as it gets when using BlitzForrest. Simply let BlitzForrest know what detail you want your trees displayed at, and at what relative scale your world is, and you're ready to go!

Features:
• Easy-to-use functions, which automatically take care of all optimizations transparently
• Automatically optimized loading procedures, offering unmatched loading speed with thousands of trees
• Automatic single and minimal-surface render optimizations for realtime display of thousands of trees
• Automatic level-of-detail (LOD) optimizations for amazing performance
• Optimal mesh regeneration and optimization system with possible realtime tree manipulation


BlitzGrass Library:
BlitzGrass provides you with an easy way to add infinite amounts of dense, realistic, and extremely fast grass to your Blitz3D world. BlitzGrass generates grass and adds it to your terrain automatically, additionally batching grass meshes for maximum performance. Since BlitzGrass uses a built-in paging system, there's no need to pre-load grass - everything is loaded as you move around in you're world. This means that you're world could be 1000 or 1000000 units long - it makes no difference to BlitzGrass.


Ricky Smith(Posted 2007) [#2]
Very useful - Thanks !!


t3K|Mac(Posted 2007) [#3]
whew. very nice. decent. great. i think i let my grassengine die and use yours ;)


IPete2(Posted 2007) [#4]
thanks very much nice one

IPete2


Mikele(Posted 2007) [#5]
Thanks John!


slenkar(Posted 2007) [#6]
thanks! some great code there


jfk EO-11110(Posted 2007) [#7]
These numbers sound really good. But two things: you should use a ground texture that disguises the grass quads bottom lines. Basicly a texture that has about the same hue and birghtness as the grass itself. This will make it look much better.

And 2nd a question: how does it handle alpha, is it sorting it, and how does sorting interact with other alpha objects in the scene?


John J.(Posted 2007) [#8]
you should use a ground texture that disguises the grass quads bottom lines. Basicly a texture that has about the same hue and birghtness as the grass itself. This will make it look much better.

Well of course. Remember that the screenshots above and the demo are just for demonstration purposes - when I actually used this naturally I used a matching ground texture.

And 2nd a question: how does it handle alpha, is it sorting it, and how does sorting interact with other alpha objects in the scene?

The grass quads are not individually sorted, but each batch should be. This means that there will be some incorrect alpha, but hopefully not too much.

These numbers sound really good. But

I have used both the tree and grass system in my (canceled) BattleTanks III project, and I know for a fact that they run very well (about 90 FPS on a GeForce 5200 at moderate detail settings):



Vorderman(Posted 2007) [#9]
That screenshot looks brilliant!


jfk EO-11110(Posted 2007) [#10]
That's looking much better. I wish I had access to this before I added grass to my project. The one that I use utilizes CopyEntity. It's pretty fast, but a contingent of 3 thousand quads already has an obvious impact on the framerate of a "worst-case-rig" radeon 9200se.

Although, it's not only the number of tris and surfaces that makes the diffrence. The higher the grass (y-scale), the more the quads are overlapping onscreen, resulting a high number of alpha levels for the renderer. At the other hand: the lower the height of the grass, the more quads you need to cover the ground. It's a dilemma.

So what is the trick of your method that allows to render 10'000 on a 5200 without high costs?


John J.(Posted 2007) [#11]
Although, it's not only the number of tris and surfaces that makes the diffrence. The higher the grass (y-scale), the more the quads are overlapping onscreen, resulting a high number of alpha levels for the renderer. At the other hand: the lower the height of the grass, the more quads you need to cover the ground. It's a dilemma.

So what is the trick of your method that allows to render 10'000 on a 5200 without high costs?

Like you mentioned, there are three major performance factors on a video card:
#1: Fill rate
#2: Batch count
#3: Polygon count

Notice that polygon count is the least important. On practically any video card past a GeForce 2, polygon count has become quite trivial in comparison to other factors (like batch count and fill rate).

Batch count refers to the number of individual draw calls Blitz3D (or whatever engine you use) has to make. By combining multiple objects into a single object, you can reduce the draw calls, even though the polygon count stays the same. This can lead to EXTREMELY high boosts of frame rate. For example, drawing 20,000 mesh trees individually on a GeForce 7800 GT barely runs at 1 FPS, while grouping them into ~20-30 batches runs at 150 FPS.

And often the most important (depending on the nature of your geometry) is fill rate. Like you mentioned, reducing the y-scale reduces the amount of pixels used by each grass quad, and therefore boosting performance. If you have a modern card, grass shouldn't be too much of a problem, but cards like a 5200 have terrible fill rates and really benefit from lower grass heights.

The only real way to avoid the fill rate bottleneck on older cards is to either scale down your grass, or possibly try alpha-rejection on your textures (called "masking" in Blitz3D). Alpha-rejection rejects transparent pixels from being unnecessarily processed from the pixel pipeline, which can help slightly (although I don't think Blitz3D allows both masking and alph at the same time).

So what is the trick of your method that allows to render 10'000 on a 5200 without high costs?

Batching and low y-scale. There's not much else you can do beyond that - at this point you've pretty much reached the limits of your hardware.


jfk EO-11110(Posted 2007) [#12]
Open land as in your screenie is very hard to achieve. I am rather trying to design levels with a low camera range. For example, a canyon enviroment that allows rich vegetation at all times.


John J.(Posted 2007) [#13]
Open land as in your screenie is very hard to achieve. I am rather trying to design levels with a low camera range. For example, a canyon enviroment that allows rich vegetation at all times.


You mean like this? (p.s. the trees are just placeholders - I know they look bad)

(View movie here)



I'm designing my current game engine to handle it all - dense swamplands, wide open grassy planes, mountainous forests, etc., :)

(I guess this is a little bit off topic, but I'm sure some of you are a little interested in why I'm giving my old code away ;) )


Fuller(Posted 2007) [#14]
what did you make the trees in? I wish I could make better trees


John J.(Posted 2007) [#15]
what did you make the trees in? I wish I could make better trees

I used Blender. The trees above are really very simple, just a square-ish trunk with a dome top textured with leaves.


msx123(Posted 2007) [#16]
Xira engine is your new engine with c++?


Danny(Posted 2007) [#17]
Thanks again John, this looks very cool! !!!!


semar(Posted 2007) [#18]
Yup, very nice, thank you John for this really *good* tree library !

Sergio.


John J.(Posted 2007) [#19]
Xira engine is your new engine with c++?

Yes, that's what I'm planning on calling it. It's actually more of a framework, so unfortunately I don't think I could port it to BlitzMax without converting the entire engine (though I probably could add my tree/grass system to something like Flow). When it's done it'll probably be more like Torque to the "casual" developer, but with a very powerful world/script editor and many advanced features like hardware grass animation, highly optimized 3D trees (for 50,000+ tree forests), splatting terrains, possibly dynamic tree destruction, portal occlusion, horizon occlusion (hopefully), full shader support + fallback system (since I'm using Ogre for rendering) etc. The demo used to make the screenshots/video above (10,000 trees, animated grass, 50 physically simulated boxes) runs at ~300 FPS on a Gf7800, and ~30 FPS on a Gf5200.


Naughty Alien(Posted 2007) [#20]
John, how to place this grass chunks on to mesh terrain?? There is no specific BG command for positioning...


John J.(Posted 2007) [#21]
John, how to place this grass chunks on to mesh terrain?? There is no specific BG command for positioning...

You don't specifically position the grass. Instead you first add a grass layer (which appears everywhere), then apply a grassmap. The grassmap should be a greyscale image just like your heightmap, but instead of setting terrain height, the grassmap sets grass density.

P.S. I'm not sure if the grass map functions are working 100% - I think the axes might be inverted or swapped. Also, the grass map isn't smoothed, so the grass densities may appear in blocks. This is the one section of BlitzGrass that I never finished (and unfortunately, I probably don't have enough time to finish it now due to other projects).


Naughty Alien(Posted 2007) [#22]
yes..that should be fine with terraing made from bitmap, but what about mesh terrains?? How to use gras system with with mesh terrains?


John J.(Posted 2007) [#23]
How to use gras system with with mesh terrains?

In this case you'll have to create you're own MeshTerrainY() function that operates similarly to Blitz3D's TerrainY() and change the TerrainY() calls in BlitzGrass to MeshTerrainY() (or whatever).


Nexus6(Posted 2007) [#24]
John, dont know if I'm doing something wrong or not but I can't seem to get the grass system to work with a grassmap, it just ignores it and places the grass all over the grass layer.
In fact, you've commented out the grassmap function in your demo.
Any idea's what i might be doing wrong or what might be wrong with the grassmap function.


John J.(Posted 2007) [#25]
Nexus6: I'm not sure why that's happening, but like I said the grassmap feature wasn't finished, and I probably don't have time to finish this when I already have a much nicer grass system working in C++.

Hopefully the grass library will at least provide a good starting point for anyone who needs it (although the tree system should be 100% working).

P.S. If you're "fluent" in C++, my latest project might be helpful here (especially GrassLoader.cpp), since it's density/color map features are complete.


Tom(Posted 2007) [#26]
Nice stuff John! That pic above is pretty, but tell me, can we have the StickyBoulderOnSlope code too? :P


Mortiis(Posted 2007) [#27]
Great system thanks! Is it possible to implement it into a world editor to put grass in certain places? I don't ask you to do it but is it just possible? :)


Svenart(Posted 2007) [#28]
this is really great, thank you very much. Can anyone tell my how I can load treemeshes instead of images?


John J.(Posted 2007) [#29]
this is really great, thank you very much. Can anyone tell my how I can load treemeshes instead of images?

BlitzForest isn't capable of doing that, unfortunately.

Is it possible to implement it into a world editor to put grass in certain places? I don't ask you to do it but is it just possible? :)

With grassmaps it is, but like I said above I don't think the grassmap support included is fully working.

On these lines:
		xp# = Rnd(x - BG_BlockSize, x + BG_BlockSize)
		zp# = Rnd(z - BG_BlockSize, z + BG_BlockSize)
		
		Density = BG_sysArrayGet(em\GrassMap, scl*xp, scl*zp)
		If Rand(0, 255) < Density Then

If you set Density to a value between 0 and 255, depending on how dense you want the grass at (xp, zp), you should be able to have full control over the density.

Nice stuff John! That pic above is pretty, but tell me, can we have the StickyBoulderOnSlope code too? :P

You mean the soft-edged minimap? :D


Tom(Posted 2007) [#30]
/me rubs eyes.. so it is! :P


Rick Nasher(Posted 2014) [#31]
Anybody ever got this(the grassmap system) to work with a BlitzTerrain?'

Appears John J was right about it not being 100% OK cos I noticed the grass is partially rendering off the map and gives an "offset out of range" error.


Rick Nasher(Posted 2014) [#32]
This screenshot demonstrates the grass on terrain:


And this one where things go wrong(no longer getting the "offset out of range" error anymore though):


For anybody who doesn't have the BlitzForrest/BlitzGrass (I see the links are dead),
here's a download link for the original package with my addapted code(GrassyTerrain TryOut.bb) and some media included.

Help on this one is greately appreciated.


RemiD(Posted 2014) [#33]
What do you want exactly ?

Do you want to prevent the grass meshes to be positioned outside of the terrain ?
Do you use a Blitz3d terrain or a custom mesh terrain ?


Rick Nasher(Posted 2014) [#34]
Indeed, it's running out of bounds, probably because of the positioning and as John J. mentioned above:

"P.S. I'm not sure if the grass map functions are working 100% - I think the axes might be inverted or swapped. Also, the grass map isn't smoothed, so the grass densities may appear in blocks. This is the one section of BlitzGrass that I never finished (and unfortunately, I probably don't have enough time to finish it now due to other projects)."

I'm using a standard Blitz3d terrain, scaled 8x200x8, that I've included in the above download.


RemiD(Posted 2014) [#35]
I don't have time to read the code but what i would do to have a lot of grass on a terrain is to use a colormap to texture the terrain and use a specific color for the grass.
Then use a system similar to a single surface particle system to position the grass meshes around the player, and use the same specific color for the grass texture. This way it should produce the illusion of unlimited grass.
You can also use several shades of green to make sure the different grass meshes are visible.

Also about grass on terrain, you may be interested in the example "Blitz3D\samples\AGore\GrassDemo"

Good luck.


Rick Nasher(Posted 2014) [#36]
Yeah I know how to do it in theory but getting to run as fast and smooth as in BlitzGrass is something else. Weirdly enough the GrassDemo you suggested is giving me MAV's on loading textures and sprites with alpha flags set. Perhaps an extension(fastext?) playing tricks on me.


Rick Nasher(Posted 2014) [#37]
Found the culprit: ClearTextureFilters

disabled it and go.


Rick Nasher(Posted 2014) [#38]
Nevertheless: not nearly as good(fast) as the BlitzGrass thing unfortunately. I don't need a whole lot of grass, I just need it in patches on some places, therefore a grassmap would be more flexible and useable. Thanks anyway.


Hotshot2005(Posted 2014) [#39]
There was TREE and Grass party for Blitzbasic but now it is on sale for Darkbasic pro only I think


Rick Nasher(Posted 2014) [#40]
Yeah I know, that's why I'm after the previous version: BlitzGrass, but it's bugged unfortunately.


Rick Nasher(Posted 2014) [#41]
Hi all,

I was doing my own grass thing, then I stumbled upon this one, which seems pretty brilliant: Grass on a landscape (lite version) by Matt Merkulov




I modified it so one can load their own terrain or use the in-build procedural terrain as in the original, and made it a bit more modular. Future enhancements would be: custom bush models and a grass/bush map.



Works great sofar but, I would now also like to load 3D models for the bushes to create a more diverse plantlife and flexibility. I'm attempting to do this by using below line instead of the in-build procedural bush:

m=LoadMesh("Plant Imperata N300813.3DS") ; <<< causes MAV later in program.




But I'm gettting a MAV in CreateBushes() function on(even though it can load the model successfully) on this line:

AddMesh m2, m ; <<< fails w MAV if BusModel contains Loaded Mesh?





Any body got a clue why? (code with bush model on link here )


Yue(Posted 2014) [#42]



Download code.
https://code.google.com/p/heightmap-dynamic-grass/


Rick Nasher(Posted 2014) [#43]
@Yue:

I know about that one, but it's more slow and not what I'm looking for as I don't really need full grass coverage. Besides I don't think it will look nice on standard Blitz3D cos will eat up it's speed, which I need for other stuff too. Just an occasional bush here and there will do, but with different types of vegetation.

Density I can increase:


I just don't get why it won't let me add 3d models instead of the ones generated in the code..

What am I missing?


Rick Nasher(Posted 2014) [#44]
Update:

OK, found that I *can* replace the in-code generated bush with a loaded mesh.
I now added a grass quad in place pf the original bushtype 1. So it now has a mixture of bush type2 and grass:


But:
1) It apperantly only works with a simple thing like a quad for some reason.
2) I noticed that if I increase the density beyond a certain range I also get a MAV, so perhaps it's a size/memory issue?

If anyone has an idea it's greatly appreciated.


RGR(Posted 2014) [#45]
This video looks rather nice, Yue
The only thing which is in my opinion annoying is the wannabe lens flare effect.
Looks as if the poor guy has a big ball around his left foot most of the time.

My opinion on lens flares: if you see lens flares in real life then urgently go to a good doctor. ;-)
No normal person sees lens flares while walking in the sun. Maybe if he runs around looking through two cameras fixed in front of his eyes all the time ... but that's quite unusual, too ;-)


Rick Nasher(Posted 2014) [#46]
@RGR: True, but if you are watching a movie(one could consider a game as an interactive movie) or when wearing certain glasses you might experience something like it.

Besides all that: a game isn't always a real life representation, just good old mindless fun with lots of weird effects.


Hotshot2005(Posted 2014) [#47]
The links is dead :(


GSimms(Posted 2014) [#48]
Sure, they are terribly old!


Rroff(Posted 2014) [#49]
Link in the OP atleast works for me.


Rick Nasher(Posted 2014) [#50]
@Hotshot2005: Heyhey, which one do you need? I probably have it and can put it up for you as I was on the lookout for something that could give a nice diverse 'realistic' vegetation.

But ought to warn you: neither one of the pieces of these code is finished and bugfree, so that's why I attempted to do something myself and found that "Grass on a landscape (lite version) by Matt Merkulov" helt most promise as a foundation.

Managed to get it to swallow a vegetation map(different colors for different plants), my own 3d plant models(quads and combined quads using masked textures rather than alpha) and trees, plus I added a bit of simple wind. But too slow for my needs. See my last post here: http://www.blitzbasic.com/Community/posts.php?topic=102163#1236462


Hotshot2005(Posted 2014) [#51]
I used to have Grass and tree party but I have lost them :(

Having realtic grass and tree on various different terrain height does added bit of extra things to it instead of looking so bland!


Rick Nasher(Posted 2014) [#52]
Unfortunately Grass/Tree party seem to have gone down the bit fields. :-( indeed.