Ways to optimize for RenderWorld()

BlitzMax Forums/MiniB3D Module/Ways to optimize for RenderWorld()

ima747(Posted 2007) [#1]
I'm looking through my code and in a state where I'm testing and optimizing where possible. At the moment the only signifigant time hog in my loop is RenderWorld(). With about 730 entitys (almost all simple cubes) it takes 40-45 millisecs per renderworld(). Granted I've got a lot of entitys, but they're all very simple, is there any kind of optimization I could be looking to do with camera settings, or any other tricks etc?
They all are within my camera view range so sadly I can't tweak that. They're also all inside my fog range.

I tried using EntityInView to determine something was visible and use HideEntity if it wasn't visible, but I assume render world already basiclly does this internally because it improved the renderworld() time down to 34-38millisecs, but the frame rate was exactly the same, so the time was just taken up with my code, rather than the renderworld code. (maybe there's a way to optimize EntityInView? or something I can do to do fewer checks, rather than every object)

Any thoughts?


Dreamora(Posted 2007) [#2]
What you need to do, and what is the only solution btw, is reduce the surface count drastically. Its no problem with Renderworld but with your highly anti-GPU oriented 3d space sadly.

if you need them to be single moving, search for single surface on the blitz 3d board unless you know how it works. (depending on your needs you might adapt it to a sector based single surface)

if you don't need them to be movable as own things, use addmesh to create larger mesh chunks which can be sent as one to the card instead of sending XXX single pieces and blocking the connection.


ima747(Posted 2007) [#3]
Hmmm I was affraid of that. They have to be seperate entities since the player can interact with any single one at a time and I really don't want to write my own code to tear apart a giant mesh to find the box that they're trying to interact with etc.

How Fast is addmesh? might it be faster to hide all entitys, and add each one to a single mesh (and how would I go about that preserving position, alpha, scale etc) then it just has to send that 1 mesh since everything else is hidden. then wipe the mesh, update my entitys, and repeat... I'm assuming that's a stupid idea, but if add mesh is fast and sending that many entitys is slow (obivously is) then is that worth looking into?

Something that just poped into my head is handling the EntityInView my self and then grouping entitys into blocks of 4 or so and just testing for visiblity on that. that would cut out 75% of the testing time and since many would be turned off it should in theory limit the number being sent to the card... that is assuming that a hidden entity isn't sent at all...


Dreamora(Posted 2007) [#4]
You can't use addMesh if they need to be handled seperate.
Using a single surface system for this task would be much faster and more powerfull most likely as well
the alternative is to wait for the next release which was mentioned to include an octtree scene graph which is much better performance wise than your second idea


ima747(Posted 2007) [#5]
Hmm interesting.

I'm not sure I fully get the single surface thing. Haven't found a thread explaining it yet, but from what I've found it sounds like it's for 2D sprites being displayed on one surface, so essentialy making 2D in 3D (unless I'm miss-understanding which I probably am) which won't help me since I'm working in 3D (cubes, not squares). Hopefully I'm just missing something obvious, is there a specific thread I should search for, or can you give me a brief description of the concept so I know what I should be looking for?


Dreamora(Posted 2007) [#6]
Single surface essentially means that you have pivots, that represent single object positions, but that you actually use one single surface for the object to be rendered.

Depending on how you implement it, this is called batching (if you add all cubes you see to a "render mesh" through add mesh and clear its surfaces after renderworld() ) or instancing if you use the same geometry data over and over again with different transformation matrices etc. (btw: did you try out copyentity which does the same?)


ima747(Posted 2007) [#7]
Using CopyEntity in place of create cube gets me from 36-37millisec down to 31-33, which equates about 2.5fps so that certainly helps. It saves about 2-3 megs of ram as well. but since my app only uses about 4-5 total it's a bonus I'm less concerned about but still nice.

So from a lower level view using copyentity I know re-uses the mesh geometry for each object, but since it still has to send the transformations for each object I assume I'm still doing about 730 sends to the card per frame, but only 1 geometry send. so it's a start, but there's still a lot of seperate things being sent. Many of the cubes have the same scale or texture most of the time, is there a way I can flag them as identical texture, or identical scale, etc. like the the identical mesh, so that it only sends "there's a copy of that one at this position too" instead of "there's an object, with the same mesh that's here, this size, this texture, etc etc."


Dreamora(Posted 2007) [#8]
The only real way (beside using batching) to get higher speed is using kleptos version and rely on VBO and more modern technics than DX7 age technology which is what the regular miniB3D targets.

In either case: you will most likely need to polish up your 3d programming knowledge to get this amount of objects working on a regular grade card ...


ima747(Posted 2007) [#9]
Sounds like it. Thanks for all the help, much appreciated!