Grass placement

Blitz3D Forums/Blitz3D Programming/Grass placement

Naughty Alien(Posted 2006) [#1]
..I would like to place grass randomly on my terrain(not done by heightmap within blitz, but exported as a mesh from MAX)..is there any useful function someone wrote maybe?? if not,whats the best way to achieve this on such a terrains?? Any help is really apprechiated..


b32(Posted 2006) [#2]
I think the easiest is using LinePick:
http://www.blitzmax.com/Community/posts.php?topic=62925


jfk EO-11110(Posted 2006) [#3]
Not sure if it's a good idea to save a whola lotta grass in mesh and then load it into a level. Real dense lots of grass tend to slow down things. For grass you need to use some tricks. Additionally, think about to animate the grass (well not with an animated mesh, but with some simple entity rotation etc.). Today static grass may be a bit poor.

Suggestion: use DDS DXT3 alpha masked textures with the mask flag to get best results and intact z-order!

Grass depends on the topography of the landscape. is it rocky, has it hills, canyons or is it entirely flat as the netherlands.

Think about to use Grass patches, eg. made of several crossed (like in tictactoe) quads, eg: 3*3 quads, all of them scaled eg: w6:h1.

THen align them to the ground using linepick and aligntovector or so. If this initialisation takes too much time then cache the data to a file, and make the app load the data instead of linepicking.

You may use Entityautofade with Grasspatches to speed things up. as long as the gound texture has the same brightness, main color tone and contrast then you don't need grass in the distant areas.

A Green virtual grass layer texture would be useful to determine where it may grow and where it shouldn't This may be a simple image that fits your grass planting raster, that's especially useful when there are streets, buildings etc.


Ross C(Posted 2006) [#4]
Bitmaps are quite usefull for placement of grass. You can store additional information in the colour channels too.


Naughty Alien(Posted 2006) [#5]
..how this linepick working actually?? I have to define 2D area over mesh I wanna use for grass placement, and then do this linepicking and read PickedY for every grass entity I wanna place?

pick=linepick(x,100,z,0,-200,0,0.1)

and value -200 means what exactly? if I put it 200, is it same value return with PickedY as well as with -200??


vivaigiochi(Posted 2006) [#6]
use a plugin added to max (glue...)
Use this plugin for place a spline (initially this spline is a circle) onto your mesh. after use the spacing tool to place your grass (or mesh) and finally export all your grass in a separate b3d file. this is one solution...


jfk EO-11110(Posted 2006) [#7]
As I said before, storing all grass in one mesh may be very slow. You can fragment it at runtime, using someting like the clusterize example from the archives.

linepick works this way:

x,y,z,w,h,d

so -200 means the linepick on the Y axis goes from 100 to -100, practicly from heaven to underground. When you use 200 instead, you won't pick the ground. Also check out pickedNX etc.


Panno(Posted 2006) [#8]
jfk wrote :Suggestion: use DDS DXT3 alpha masked textures with the mask flag to get best results and intact z-order!

is this true ? no moore a extra zorder routine ?

hmm dunno


jfk EO-11110(Posted 2006) [#9]
Z-order problems only appear in alpha mode. My Suggestion was to use the Mask flag. When you use DDS (DXT3) textures with alpha information for the Masked mode in Blitz3D then the alpha data will be used to mask the texture in a very smart way. The contours will be interpolated, depending in the alpha values. In other words: no more blocky contours of masked textures, as well as no more darkish contours (fade to black artefacts).

Tipp: If you blur the contours then the alpha will also be blured and therefor the mask outline won't jitter too much.

When using photoshop you should not use an additional alpha channel, but make use of the unpainted or erased areas on the RGB layers. (Background layer must be transparent by default)


Naughty Alien(Posted 2006) [#10]
...in order to make it really fast and nice, my approach was this..first, I create array of plain pivots all around terran where i wanna put grass mesh..then I create second array for grass meshes itself, let say 500..now, what I did is that when I move camera, I check given distance from camera (let say 300) and I place grass from grass array in to positions of those pivots whats within range of 300..every grass mesh outside of that range is repositioned in to new positions where is the pivots within given range..so, it would work fine, and very fast since all time is the same amount of grass units in visible range BUT..I didnt realize that pivot array taking so much processing time!!..even without anything on scene, without any mesh, after I create array of pivots, and do tests with flip false..I got 35 FPS..ha!..where did my processing power went?? I repeat, I didnt update anything in main loop, just create array of pivots, and thats all..no loaded meshes of any kind...how come pivots is so 'greedy' ?? It seems that Blitz3D rendering my fully textured level with bloom and DOF with 48K polys at 59 FPS and bunch of pivots with flip false reaching magnificant 35 FPS...hehehe..this is sexy..I love it....


Naughty Alien(Posted 2006) [#11]
..okay..it seems that major slowdown was happen becouse I use to play with arrays, rather than with Types..instancingalso working damn faster than generating grass entity by itself..my suggestion...run away from arrays with such a things..types is the king..


t3K|Mac(Posted 2006) [#12]
my approch is setting all grass meshes in my level. then i use entityautofade. that works ok for me. no overhead in types/arrays/.... the trick is, a grass mesh consists of a bunch of grass quads (about 25) using single surface technique.
it did just a testlevel, so in "real-level" it might be slowing down... i'll see.


Justus(Posted 2006) [#13]
Once read LinePick was not really fast, so I think TerrainY would be the better choice in this case.


Naughty Alien(Posted 2006) [#14]
I did that randomly in MAX so its fine...TerrainY will not work for mesh terrains..


jfk EO-11110(Posted 2006) [#15]
Arrays slower than types? You must be doing something wrong there, they are faster than types, espeically if you access them directly by index.

What t3kIMAC said makes sense to me. single surface patches, where a good patch size must balance surfacecount and polycount.

And finally, the number of mask or alpha levels is still very important. Today I made a function that will cross a number of quads, like a star. With about 180 quads (and the same amount of masked levels to render) the framerate dropped straight under 10. So the angle the player will look at the grass may affect the speed too.


Naughty Alien(Posted 2006) [#16]
..I cant see what i did wrong..its just array with created pivots, after they have been created I just enter in to main loop without any update, any loaded mesh, quad, or absolutely anything..and frame rate is 35! when I did same thing with Types, frame rate got 213..sooo...


t3K|Mac(Posted 2006) [#17]
i did a few tests with grass - i found a very good and fast solution (at least my pc can handle this easily).

make sure all the grass quads are singlesurface (i used copyentity for testing). place them all on the map and then use entityautofade. this gives you huuuuuge grass areas, with nearly no speed penalty. and they fade in and out just around the camera. this works like a charm.

you could boost it even more if you scale your grassmeshes like jfk said (6*x, 1*y, 6*z) and then adjust UV coords. then you'll have to set the autofade distance farer, otherwise you will get ugly fading errors.


jfk EO-11110(Posted 2006) [#18]
Alien - you must be kidden. How many pivot's did you create? a million? And even then, there's no reason for arrays to be slower. It's their nature to be faster, cause they use less vectors. Accessing types by index may be up to 10 times slower than the same with arrays, as benchmark tests have shown (ok, some blitz version releases ago).

Please show us some sourcecode that will let us reproduce your results.


vivaigiochi(Posted 2006) [#19]
I want say only this: this post is very good.
I have learning very much of it.Thanks but...
Please show us some sourcecode that will let us reproduce your results.


Naughty Alien(Posted 2006) [#20]
I'm really not kidding..I create 20 000 pivots, within array (no any textures or mesh loaded), and just went in to main loop without any processing over those pivots..I got 35 FPS..I did same with Types I got over 200 FPS..I am not sure whats going on, but its really case..

I have created this after initializing screen,

P_Pivot=Createpivot()
For i=1 To 20000

G_Pos(i)=CopyEntity(P_Pivot)


EntityAutoFade G_Pos(i),100,200

x#=(Rnd(-550,550)+Rnd(-5,5))
z#=(Rnd(-550,550)+Rnd(-5,5))
y#=0;y#=TerrainY(terrain,x,0,z)-Rnd(2)
PositionEntity G_Pos(i),x,y,z
G_Pos_I(grasscount)=Rand(-45,45)

grasscount=grasscount+1

Next

;main loop
While KeyDown(1)=0

UpdateWorld
RenderWorld
Text 10,10, FPS_framecount
Text 10,30,AvailVidMem()
Text 10,50, TrisRendered()
Flip False
Wend
End

..and thats it..I didnt do any update or something within loop..same things like this one, done with Types giving me much much more faster results...

What I am trying to do now is to place those pivots over whole area where grass should be, then define second array (or types) with grass meshes, and place them around camera in specific range around it, with specific constant number of grass planes..so, when camera move system will find wich new Pivots is within range and wich grass planes is out of range and simply reposition those grass planes out of range in to places where is new pivots within range :)) ok, sounds a bit confusing but tests i did by now showing me that it is damn fast, and results is very very nice...but to be honest i am still confused with slowdown coused by pivots in array...or pivots itself...


GrumpyOldMan(Posted 2006) [#21]
Hi Naughty Alien

I'm wondering why you're creating and storing all the pivots? One of the things I found when I was playing around with animation is that a large number of Blitz entities will slow anything down. Store the x,y,z of your positions and do a simple proximity check ie diff_x*diff_x+diff_y*diff_y+diff_z*diff_z compared to visibility*visibility (you don't need to do the square root, and you could even write a simple dll to give true or false returns).

The more I look at entities it seems that they are set up for convenience rather than speed. I'm not sure what happened with arrays versus types in your case. Did you convert both arrays g_pos and g_pos_i to types?

Cheers

GrumpyOldMan


Naughty Alien(Posted 2006) [#22]
Hello GrumpyOldMan..

Yes, I did realize that placing pivots as a reference for grass position is not smart idea at all..I just didnt realized that its taking so much processing time without doing anything in main loop actually...you are right, so I already removed pivots from scene and using them initially (placed by 3DSMAX automatically) to get position of grass..then storing their position values (x,y,z) in to an array and then passing values to DLL in order to get as a return indexes of grass what have to be replaced and appropriate new positions for them from stored x,y,z values..I limit maximumnumber of replaced grass objects about 100, and total amount of grass field around camera 500 and its really working fine (except I got some error in DLL, after replacement cycle happen 1024 times, I'm trying to figure out what did I do wrong there)...but once I clean up this it will work really nice...by the way, regarding pivots, once we create it, whats actually created, just their position x,y,z or something more?? I mean..what is the difference from my storing x,y,z values and creating one pivot wich containing this value already by his creation??


GrumpyOldMan(Posted 2006) [#23]
Hi Naughty Alien

Even though you are creating just a pivot, I believe there is more going on behind the scenes as regards to entity storage and sorting. I'm not a great programmer with any great insights but I do know that if you store 200,000 x,y,z values in an array there is a significant difference in performance to 200,000 pivots :). With regards to the grass system are you rebuilding the grass mesh based on camera proximity per render or moving already created mesh pieces?

I'll be away for a few weeks but I'll look in when I get back.

Cheers

Grumpyoldman


Naughty Alien(Posted 2006) [#24]
Hi GrumpyOldMan

System how I wanna make it working with fixed constant number of grass objects (500 units)..those grass objects is placed around player camera, within range specified in function call..so, once you moving camera, grass objects out of specified range will be repositioned in to area within range (I wanted to use already prepared pivots on terrain for those information regarding new positions for grass objects out of range, but I drop it already)..so it means that system will basically render all time 500 grass objects, nicely animated, and cover huge areas at same time with decent speed..nice feature will be also control over density of grass, simply resizing range area on to smaller reasonable value..


t3K|Mac(Posted 2007) [#25]
i have packed a small demo of my grass system:

www.delivery-game.com/grasstest.zip

its a quick hack, so do not expect high quality ;-)

it works as followed:

- loading grassquad
- make lots of copies of it using copyentity()
- position them with positionentity
- let them fade with entityautofade

thats it. this demo is rendering max. 10.000 grassquads (depending on your LOD Range of course)


Danny(Posted 2007) [#26]
Hi, I haven't followed this thread, so I might be stating the obvious, but when I set the LOD level to all the way, it's getting dead slow (with only 5000 tri's!?!) - even though I've got a beafy computer/graphics board.

Are you copying quads using copyEntity or are you using a single surface system?!

D.


t3K|Mac(Posted 2007) [#27]
in this hack i am using copyentity. a huge grassrange isn't possible with nowadays hardware. thats why AAA games limit the grass rendering distance. with this demo, you can have a decent amount of grass around your player/camera with only a few lines of code. and best thing is, you need absolutely no code&calculation in your mainloop for fading grassquads. sure you can optimize this system using real single surface system and grassquad-blocks but thats another one...


Naughty Alien(Posted 2007) [#28]
..I just finished my system few days ago, its working a bit different..first, you dont have to make such a huge number of gras entity copys..here is a steps

-define how many gras units you want around your point of interest (camera)

-define distance from your point of interest you wanna cover with grass units

thats it..system will check for grass units outside of range and simply replace them within empty space within range..it means you dont have to create huge number of copys and then entityautofade them...on this way you create 1000 units and you have all time (in memory and on scene) actually just 1000 units with excellent cover over whole area since they automatically repositioning themselves once they get out of specified range...its working trough DLL and its really fast...it has been purposely done for our upcoming 3D platformer...I'll update forum once we come out with Practice level..


t3K|Mac(Posted 2007) [#29]
i updated my version. replaced CreateSprite() with CreateQuad() and did a few optimisations - runs at nearly double speed in comparison to the old version. just redownload it.


jfk EO-11110(Posted 2007) [#30]
I like this thread since grass is an important special task in a game engine.

personally I think the best solution is to use a combination of both, EntityAutofade as well as the distancebased reposition code. This way you can smoothly fade in the grass on the borders of your grass area, where the plain reposition code may show pop-in quads when you have a long range view (eg. when looking down from a hill)

some time ago I used such a reposition code that would determine the position of the grass and the rotation of it by reproducable RND numbers with a seed that is initialized by the current space sector. This way you can walk virtualy endless far away, then come back, and everywhere the grass is repositioned correctly. So, basicly you don't need to store the position and rotation of the quads. But in a smaller world it may be faster to simply precalc them and store them in arrays.


t3K|Mac(Posted 2007) [#31]
here is a little video of my latest version of my grassengine (all done in pure blitz):

www.t3k-entertainment.com/grassengine.mpg

There are only 750 grass-tris onscreen. they reposition themselves when required (based on simple distance checking). since rotation/scale/color are (pre-)stored in arrays, lightmapped grass is also available. i am using 750 copyentities() with entityautofade. right now i am optimizing the engine using singlesurface grasspatches for even better performance. i also have a small editor where i can scale/rotate and position the grasspatches by hand. lightmapped color will be read automatically - the grass blends perfectly with lights/shadows. the grass is animating too (optionally) - but in this video you can't see it very well, 'cause the camera is always moving.

at my rig the engine performs about 130-200 fps (without singlesurfacepatches).

@naughty: whens your practice level out? i'd like to see your grassengine in action.


jfk EO-11110(Posted 2007) [#32]
My player can't handle the mpeg.

If you use Single surface then you have to z-sort the tris each frame.

Using Copyentity isn't that bad. When you use DDS in alpha mode then you only have to resposition the copies in a for loop around the player, eg: for x=xp-100 to xp+100 and the same with Y. This way they will be sorted automaticly. Did I already mention (for some strange reason) using DDS alpha was running at the double speed as using BMP?


Naughty Alien(Posted 2007) [#33]
@t3K|Mac
right now I'm working on level geometry (5th world)..after that I'm going to release Tutorial level with some nice features in game (without characters at the moment), to show physics, grass engine, specular lights over surface, etc...month ago (something like that) I post sky temple level and how it will look..so, soon after I clean up geometry, I'll release small example whats going to be in regarding content itself without characters/gameplay at the moment...


t3K|Mac(Posted 2007) [#34]
@jfk:its a plain mpg. i am using quicktime plugin to play it.
i am also using dds files, not bmps. when i said singlesurface, i didn't meant to replace all copyentities with a singlesurfacemesh, i just replace some single grasspatches with a bunch of grasspatches (these are singlesurface) which cover a bigger area. so i am capable of virtually rendering more than 750 grassquads with only using 750 quads.
i will give banks a try, maybe this is faster than lots of huge DIMs. I am gonna squeeze every fps out of my grass-system.

@naughty: i cant wait to see your demo. mine is taking another bunch of weeks/months ;(