The Technology of a 3D Engine - Part Two - Page 1

Published on 20th May 2008, written by Roderic Vicaire for Games Development - Last updated: 20th May 2008

Introduction

Editor's Note

It's been
a good while since we published the first part, and the delay in
bringing you the second part is all Beyond3D's. We've had Roderic's
series in mostly complete form for ages, and we've just not had the
time to work with him to get it into shape. Apologies to Roderic
especially for that, as he hunted recently for his new job. Good luck
at Funcom!

In this part of the article series, Roderic
talks about scene management and its specific implementation in his
engine technology. What he describes is an elegant optimised
implementation of understood techniques, pulling together ideas and
application using accessible design patterns, to make them easy to
consume in code. Enjoy part 2.

Scene Management

Scene
management is central to a 3D engine, as it's a feature of the engine
that the user will have to deal with daily. A usual way to handle scene
management is through what's called (and often inaccurately) a scene
graph: a hierarchical (The torch is in the hand of the hero), spatial
(An orc is near the hero), and stateful (The flame of the torch is
alpha blended) structure.

The issue with that structure
is that it tries to be a jack of all trades, and becomes a master of
none. There have been a lot of discussions on the Internet about that
problem, and the general consensus seems to be that über scenegraphs
should be discarded (¹).
Some modern games also have no scene graph at all, nor any hierarchical
structure to represent the scene. Although this might work well for a
single given title, if an engine is to be used on many titles and
provide functionality to ease the work of its user, having a
hierarchical tree is something you would want nonetheless, if only
because of the transformations (location and orientation) of the
objects.

Take the torch in the hand of the Hero example
above; when the hand moves, so must the torch, and if it's a child node
of the hand node in the hierarchical tree, it'll happen automatically.
The problem with the omnipotent (or über) scene graph is that by trying
to solve all problems at once, it's usually not good at solving any of
those sub problems well. Two nearby objects may be in different branchs
of the scene graph because they are parts of two unrelated hierarchies.
Also consider two objects having the same rendering properties...

As
an example, imagine the following scene. Two warriors are fighting each
other with magic swords, both using particle effects to show they are
magic. Obviously the two swords will be hitting each other, so very
close from one another (close spatial relationship), but each being in
the hand of a different character, they'll belong to two different
hierarchies (foreign hierarchical relationship) and the particles used
to show off the magic essence of the sword are identical (identical
rendering properties), yet duplicated.

Where a single
structure can't solve all the problems at once efficiently, it can
solve a single problem, which naturally leads to wanting specialised
structures for each kind of relationship, just like a recent article on
the subject (²)
suggests. Using that article naming scheme, the engine's structures
will be views, and data will be objects. That result in an engine
having the following views:

A scene tree, which is the hierarchical view of the world (for handling hierarchical animation).

A spatial graph, which is the spatial view of the world (for grouping nearby objects together, for culling).

A render graph, which is the state optimal view of the world (for grouping objects by states, such as shaders, materials, etc).

Seen
from the engine writer's perspective, this all sounds good. You have
different structures for different tasks, each specialised for optimal
performance, but from the user's point of view, it seems rather
cumbersome to have to manage three structures all at once.

Fortunately,
it's not a burden to the user, as it's hidden, and although the user
will be warned about the internals of the engine, he'll have a single
interface and tree to manage; the SceneTree. Objects will be
automatically inserted into the SpatialGraph and the RenderGraph, when
they are created.
Reusing the example above example, the swords will be in the same
spatial node (SpatialGraph), and since they are touching each other,
they will be in their correct hierarchy for animation (SceneTree), and
they will have particle systems sharing the same effect (RenderGraph).