Horde3D

Next-Generation Graphics Engine
It is currently 29.09.2024, 00:30

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: 17.01.2009, 23:03 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
We are currently thinking about ways to optimize the scene management. Profiling has shown that the update of the render queue is by far the most expensive function for Chicago. So here is the plan of attack:

Currently we have the scene graph structure which is used for hierarchical transformation and also culling, accelerated by an AABB tree. The new idea is to split that scene graph in two components: a scene tree which is solely responsible for the node transformations and a spatial graph which does the culling. There is not much difference for the user, the spatial graph is completely transparent: When a scene tree node is updated, it is automatically rearranged in the spatial graph. The spatial graph finally generates the render queue. The spatial graph can be something like an octree or portal system. But as default implementation I would opt for something very simple but useful called multibound (see http://geck.bethsoft.com/index.php/Occlusion_Culling). Basically a multibound is just an AABB which is placed manually by a designer at appropriate locations, e.g. a room. All objects which are in the multibound are culled in one go. The multibounds could also be used in combination with hardware occlusion culling which makes them much more effective.

This system would give a better separation of concerns (transformation hierarchy and culling based on spatial proximity/locality). Multibounds would be represented as scene nodes, so they could also be transformed, for example when the whole world is shifted. That also means that no additional API is necessary and adding support in the Horde editor is rather easy. The current AABB tree would be removed which makes the scene tree updates cheaper and amortizes hopefully the additional costs of the spatial graph processing. I think that system would give to users a lot more chances to optimize performance of complex scenes.

Any thougts on that?


Top
 Profile  
Reply with quote  
PostPosted: 18.01.2009, 02:23 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
A spatial graph supporting cycles could be very useful (and powerful).
This would allow games with extremely large indoor areas to be rendered easily.

e.g.
* The spatial graph root has 1 child node called "RoomA"
* "RoomA" has 2 children: "RoomB" and "RoomC"
* "RoomB" has 2 children: "RoomC" and "RoomA"
* "RoomC" has 2 children: "RoomA" and "RoomB"

The code for stopping infinite loops is pretty simple. The renderer can increment a counter once per 'Render' call. When a spatial node is visited, this ID is recorded. If the recorded ID is equal to the current ID, then this node has already been visited this frame:
Code:
frameId++;
TraverseSpatialGraph( spatialRoot );

void TraverseSpatialGraph( SpatialNode n )
{
  if( n.lastFrame == frameId )//already traversed this frame
    return;
  n.lastFrame = frameId;
  if( !Cull( n.scene ) )
    TraverseScene( n.scene );
  for_each( iterator = n.child_spaces ... )
  {
    if( !Cull( *iterator ) )
      TraverseSpatialGraph( *iterator );
  }
}


[EDIT] Thinking some more about a spatial-graph, it might be useful for the user to tell Horde (or for Horde to figure out internally) which multi-bound/spatial-node the camera is currently inside of.

For example, in this example level there are 8 rooms in a circle pattern, each room is connected to 2 other rooms.

If Horde knows that the camera is inside of room "B" then the scene traversal is more efficient than if we always started at some particular "root node" (N.B. in my picture there is no root node - all nodes are equal in the spatial graph).

Starting from "B" (in my picture), the graph traversal would look like:
Code:
B = rendered
|- A = rendered
|  |- B = culled (already rendered this frame)
|  |- H = rendered
|     |- A = culled (already rendered this frame)
|     |- G = rendered
|        |- H = culled (already rendered this frame)
|        |- G = culled (out of camera frustum)
|- C = culled (out of camera frustum)


Top
 Profile  
Reply with quote  
PostPosted: 18.01.2009, 12:06 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
DarkAngel, thanks for your feedback, it is very appreciated.

I don't quite get your point of the room cycles. How does the system profit when each room includes any other room? For me the spatial graph is a logical real-world representation of the spatial relation, so the huger room could include the smaller room (which makes a tree) but not the other way round.

Concerning the second part of your answer, do I understand correctly that for the culling algorithm you describe, you need connectivity information between the spatial nodes? So you describe basically a portal system? The point of the multibounds is that they don't have portal/connectiviy information. They are just a hint (set by a human) for the engine that it is reasonable to treat the objects in the designated area (the multibound) as a single entity for culling. For example, this can make sense for a room which has many smaller objects (e.g. chairs, tables) to speed up the culling, especially if that multibound is occluded by the walls around the room.


Top
 Profile  
Reply with quote  
PostPosted: 19.01.2009, 03:10 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
Quote:
The point of the multibounds is that they don't have portal/connectiviy information. They are just a hint (set by a human) for the engine that it is reasonable to treat the objects in the designated area (the multibound) as a single entity for culling. For example, this can make sense for a room which has many smaller objects (e.g. chairs, tables) to speed up the culling, especially if that multibound is occluded by the walls around the room.

Perhaps my idea should actually be a 3rd graph then?
Graph #1 = Scene transformations tree
Graph #2 = AABB / culling tree
Graph #3 = Connectivity / traversal graph
marciano wrote:
I don't quite get your point of the room cycles. How does the system profit when each room includes any other room? For me the spatial graph is a logical real-world representation of the spatial relation, so the huger room could include the smaller room (which makes a tree) but not the other way round.
I don't think this idea would help much in simple scenes like the chicago sample, so I'll use a city as an example scene:
Image

First we have the traditional spatial tree (AABB tree/quad tree/etc...), where each node has one parent and can have many children.
The root node contains many city blocks, each block contains many buildings, each building contains many floors, each floor contains many rooms.
This tree is good for frustum-culling purposes, as entire blocks, buildings, or floors can be culled at once.


However, this tree is not ideal for scene traversal as we always have to begin at the root node, and we don't have any information on which nodes are visible from other nodes.
Image
For example, in the above image the camera can only see two rooms, however the renderer must:
*Start at the root node
*Cull every city block, except the one the camera is in
*Cull every building, except the one the camera is in
*Cull every floor, except the one the camera is in
*Cull every room, except the two the camera can see

We can improve scene traversal by supplementing the first tree with a non-directional graph, which describes connectivity.

Using a connectivity graph, the scene traversal can begin in the camera's current room, instead of starting at the root.
In the above example image, the camera is inside room "A", which connects to "B", "C" and the outside "o" (this would be the city-block node which contains the building).
*First "A" is rendered.
* "B", "C" and "o" are checked next. "C" and "o" are culled.
* "B" is rendered. All of the rooms connecting to "B" have already been processed, so rendering is complete.


Another example using city scene: the hierarchical-AABB layout (black arrows) and the connectivity data (green arrows) could look like this:
ImageImage
(click the map for larger version).

When rendering a node, a recursive function is called through both black and green arrows (but nodes must be counted like in my first post so they are not rendered twice).
If the user has not supplied a connectivity graph, then rendering can still begin from the root (as it does now), and will work because there are still black arrows, but no green arrows.

Quote:
Concerning the second part of your answer, do I understand correctly that for the culling algorithm you describe, you need connectivity information between the spatial nodes? So you describe basically a portal system?
It is similar to a portal system.
In my original picture, you could call the pink lines that join each room together "portals" --- If you calculated the AABBs of the portals, you could do occlusion tests on the portal AABBs instead of on the AABB of the room behind the "portal" ;)

Actually, this would probably be a required feature - When entering connectivity data, you could optionally specify an AABB to be used for culling purposes (whether the "portal" is hidden or not). If no AABB is specified for a connection, then the multibound that the connection points to would be used for culling purposes.

In most cases, connections wouldn't require an explicit AABB of their own.
However, if a "child room" has a connection to a "parent room" (e.g. Room 1 on Floor 3 has a window which connects back up the tree to Block 2), the the parents AABB test would always pass... So instead, the "portal" would be required to have an AABB of it's own.


Top
 Profile  
Reply with quote  
PostPosted: 20.01.2009, 20:28 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
Thanks a lot for your detailed explanation, it made your ideas much clearer to me. I will do some deeper thinking about the whole topic when I have a bit more time again.


Top
 Profile  
Reply with quote  
PostPosted: 24.01.2009, 22:29 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
We have integrated a very basic spatial graph now. It is just a flat list and does not yet support MultiBounds or sectors with connectivity information but it already helps to make the culling (render queue generation) considerably faster.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group