Trees and leaves

Blitz3D Forums/Blitz3D Programming/Trees and leaves

DH(Posted 2005) [#1]
Alright, I think I have it down. Please correct me on this technique.

I have been trying to learn how to do tree/leaf effects like speedtree and blitztree3d and I think I have it.

Create a mesh, parent it to the camera.

Create all your leaf quads in it facing camera.

Go through the tree list and simply move the quads to the needed location (this way they stay facing camera).

Rotate the texture a bit for the leaves and modify the texture u,v positioning to keep the leaf texture in the center.

I have been playing with this technique and it seems pretty decent.

Speed comparrisons:
Using sprites: Max in scene before I see a slow down is 1000.
Using quads and rotating the verts to match camera: can do about 4,000 before a noticable slowdown (before the frame rate comes off strong).
Using the above method: about 12,000 quads before a slow down.

Now that makes a huge difference... Each tree having roughly 40 leaf quads, rotating and such yet still facing camera. That gives me ...

25 trees for the 1st method
100 trees for the 2nd method
and 300 trees for the method described at the beg of this post.

Not that I NEED 300 trees, but the ability to have more, means that the system can do other things than just do trees...

Anything I could be doing better????


I also found out that when modifying a mesh's structure, dont leave the function (or call other functions). It impacts the performance somewhat. It may not be noticable on a few operations per mesh, but when going through a list of 2000 verticies, it gives a hella slow down..

For example:
Function ModifyLeafs()
	Local L.Leaf
	Local RX#,RY#,RZ#

	For l.Leaf = Each Leaf
		For x22 = 1 To 4
		X# = Rnd(-10,10)
		Y# = Rnd(-10,10)
		Z# = Rnd(-10,10)
		X# = X# + 5			
		Y# = Y# + 5	
		Z# = Z# + 5	
			;Rotate3d()
			VertexCoords(L\Surface,L\Vert[x22],X#,Y#,Z#)
		Next
	Next
End Function


is 25 ms faster then doing this:
Function ModifyLeafs()
	Local L.Leaf
	Local RX#,RY#,RZ#

	For l.Leaf = Each Leaf
		For x22 = 1 To 4
			;Rotate3d()
			VertexCoords(L\Surface,L\Vert[x22],RotX#(),RotY#(),RotZ#())
		Next
	Next
End Function
Function RotX#()
	Return Rnd(-10,10)
End Function

Function RotY#()
	Return Rnd(-10,10)
End Function

Function RotZ#()
	Return Rnd(-10,10)
End Function


Just to give you an idea on my system:
Fresh install, default Board config, XP Pro set to performance config rather then appearance config, 2.4 GHZ P4 with Hyperthreading, 512 MB DDR, 120 GIG 7200 rpm WD Special Edition, Geforce 4200 128mb


But anyway, anyone with any ideas on how i can speed up my tree process?

I was considering publishing the system in the code archives if I can get something decent cooked out.


Hujiklo(Posted 2005) [#2]
How about not randomly manipulating all the leaves and only doing a set ammount such as 150 and then just have all other leaves use 1 of these pre-set calculations...or maybe generate bunches of leaves as a single mesh and have them copied rotated and placed randomly? Would that not speed up the whole caboodle?


mrtricks(Posted 2005) [#3]
I don't get it - how is the method you describe different to using quads and moving them to face the camera? You still have to move the quads each frame.

Good tip about leaving the function though. I'll check that out for my geomod system to see if I can get it going faster...


DH(Posted 2005) [#4]
I don't get it - how is the method you describe different to using quads and moving them to face the camera? You still have to move the quads each frame.


well, doing sin, cos, or tan can get cpu heavy when it comes to doing 1,000 plus calculations. Doing rotations on verticies require 6 sin calculations and 6 cosine calculations per vertex (proper 3d rotation), Not to mention doing the dot product involved and such to find the plane facing the camera to rotate to.

This is basically how sprites operate (to my knowledge). I found that doing the calculations required to mimic a sprite were just as costly (cpu-wise) as using the sprites themselves.

Whereas doing a simple distance calculation on where to move the quad to, and letting it stay facing the camera (because it was created facing the camera, and the mesh is parented to the camera), is much more efficient.

I did quite a bit of testing with each method above (including what your describing) and have found my final method to be the most efficent to gain the results I am after.

Good tip about leaving the function though. I'll check that out for my geomod system to see if I can get it going faster...


Although it is faster not to leave the function or call others in a function, the increase in speed is unmessurable unless your doing it 1,000 + times a frame. Only updating 50 leaves I noticed no measurable slowdown, but when approaching 2,000 leaves (just the three function calls you see above doing returning the rnd() statement) and my frame rate dropped by 30%.

With this discovery, it shines me away from keeping my code as modular as possible, since I dont want to be making that many function calls for speed, yet I want to use functions like that to keep everything A. organized and B. Modular.

I doubt that someone like Alienhead will respond to this thread seen as though I am trying to create something that he sells (where in his eyes, I should just purchase it from him and save the hassle)... Although it would be benifical to me that he would respond since he has traveled this road before.


DH(Posted 2005) [#5]
Well, I have started to create the system and run into a few snags......

When modifying the leafes vertex coordinates, I tform the points of where the leaves should be (relative to the trees) into the leaf mesh which causes a bit of slow down.


mrtricks(Posted 2005) [#6]
Okay, worth knowing. How about if you're using Sin and Cos lookup tables instead of calculating them? I must admit, modular code layout is something I don't want to go away from if I can help it.


Stevie G(Posted 2005) [#7]
In my experience using the tform commands to rotate the individual quads is almost twice as fast as using sin/cos etc... You may get some speed up using Lookups for sin/cos but very little on modern hardware.


Ross C(Posted 2005) [#8]
I found look up tables were slightly slower. I agree with the tform commands being faster too.


DH(Posted 2005) [#9]
In my experience using the tform commands to rotate the individual quads is almost twice as fast as using sin/cos etc... You may get some speed up using Lookups for sin/cos but very little on modern hardware.



You are correct, the slowdown over 2000 leaves (4,000 polys, 8,000 verts) is only about 4-5 ms on my machine using Tform (which I can live with). Whereas doing a sin,cos operation (just to rotate the verts around a center point) slows the operation down 30-45 ms.

Tform is the way I am going.


I found look up tables were slightly slower. I agree with the tform commands being faster too.


My findings are the same, lookup tables are a bit slower because you still have to do a lot of calculating after you get the sin/cos lookup to rotate the verts and such. Tform converts it into the mesh's local coord, and my merely move the vert to where it should be (so 1 tform, and an XYZ addition to each vertex).


DH(Posted 2005) [#10]
http://www.blitzbasic.com/Community/posts.php?topic=46177

That is the thread to the zip for the test.. It looks pretty decent for a start. Bare in mind that the textures need work, and I need more variation in trunks/trunk textures.

I was thinking that this might be a good solution for a particle engine as well. I am unsure how particle engines work yet (haven't really had a need to get into them just yet), but if they are anything like everyone is describing (facing quads twords the camera), then this solution might prove to be a huge speed increase.


DH(Posted 2005) [#11]
update:
After some further playing with this 'camera displacement' technique of single surface manipulation, I generated the following pic:


This is 6,000 trees runing as a billboards using the camera displacement technique. (the fps are low because I am running in debug and in windowed mode which gives horrid flip times) and these radeon 7000's suck.

Now if I take a few thousand from the far back and create a basic billboard out of that, I believe I can (using the system in my previous post to control the moving trees with leaves, this system for lod trees, and a huge billboard for anything over 1,000 units away as one big billboard) re-create speedtree's 1 million tree demo (probably at about 30-40 fps though which is a bit of a downfall).

This is kind of exciting!