[翻译]Scene graph(场景图)(未完)

Scene graph

From Wikipedia, the free encyclopedia

Jump to: navigation, search

场景图是一种数据结构,通常运用于 3D图形编辑软件或者3D游戏。

场景图是一种包含了渲染场景里各个对象的逻辑和空间(通常但不是必须)的组织关系。在这里为场景图下一个定义是不现实的,因为在实际运用中,场景图是程序员根据具体项目或者游戏的需求来定制的。这意味着没有谁能规定场景图应该是什么样的结构,或者不应该是什么样子。

场景图通常是一组 节点的集合,它采用 图 或者 树 作为自己的数据结构。一个节点可以含有多个子节点,但是通常只有一个父节点,对父节点的操作将影响到它的全部子节点;另外一种操作则是以“一组节点”为单位,对组的操作将自动的影响到组内的全部节点。在许多程序里,能够对一组节点做矩阵交叉变换或者类似的操作,已经是理所当然的功能了。这样可以象操作单个对象一样,操作一组对象的移动、变换、选择等等。

在另外一些场景图里,一个节点可能会与多个节点有关联。(就是IK,反向动力学)


Contents

[show]
<script type="text/javascript"> // </script>

[edit] Scene graphs in graphics editing tools

In vector-based graphics editing, each node in a scene graph represents some atomic unit of the document, usually a shape such as an ellipse or Bezier path. Although shapes themselves (particularly paths) can be decomposed further into nodes such as spline nodes, it is practical to think of the scene graph as composed of shapes rather than going to a lower level of representation.

Another useful and user-driven node concept is the layer. A layer acts like a transparent sheet upon which any number of shapes and shape groups can be placed. The document then becomes a set of layers, any of which can be conveniently made invisible, dimmed, and/or locked (made read-only). Some applications place all layers in a linear list while others support sublayers (i.e., layers within layers, to any desired depth).

Internally, there may be no real structural difference between layers and groups at all, since they are both just nested scene graphs. If differences are needed, a common type declaration in C++ would be to make a generic scene graph class, and then derive layers and groups as subclasses. A visibility member, for example, would be a feature of a layer but not necessarily of a group.

Scene graphs in games and 3D applications

Scene graphs are ideal[citation needed] for modern games using 3D graphics and increasingly large worlds or levels. In such applications, nodes in a scene graph (generally) represent entities or objects in the scene.

For instance, a game might define a logical relationship between a knight and a horse so that the knight is considered an extension to the horse. The scene graph would have a 'horse' node with a 'knight' node attached to it.

As well as describing the logical relationship, the scene graph may also describe the spatial relationship of the various entities: the knight moves through 3D space as the horse moves.

In these large applications, memory requirements are major considerations when designing a scene graph. For this reason many large scene graph systems use instancing to reduce memory costs and increase speed. In our example above, each knight is a separate scene node, but the graphical representation of the knight (made up of a 3D mesh, textures, materials and shaders) is instanced. This means that only a single copy of the data is kept, which is then referenced by any 'knight' nodes in the scene graph. This allows a reduced memory budget and increased speed, since when a new knight node is created, the appearance data does not need to be duplicated.

Scene graph implementation

The simplest form of scene graph uses an array or linked list data structure, and displaying its shapes is simply a matter of linearly iterating the nodes one by one. Other common operations, such as checking to see which shape intersects the mouse pointer (e.g., in a GUI-based applications) are also done via linear searches. For small scene graphs, this tends to suffice.

Larger scene graphs cause linear operations to become noticeably slow and thus more complex underlying data structures are used, the most popular being a tree. This is the most common form of scene graph. In these scene graphs the composite design pattern is often employed to create the hierarchical representation of group-nodes and leaf-nodes.

Group Nodes - Can have any number of child nodes attached to it. Group nodes include transformations and switch nodes.

Leaf Nodes - Are nodes that are actually rendered or see the effect of an operation. These include objects, sprites, sounds, lights and anything that could be considered 'rendered' in some abstract sense.

Scene graph operations and dispatch

In order to apply an operation to a scene graph, some way of dispatching an operation based upon what node is currently being considered is needed. For example in a render operation a transformation group-node would do nothing more than accumulate its transformation (generally this is matrix multiplication but could involve operations with vector displacement and quaternions or Euler angles instead). Whereas an object leaf-node would send the object off for rendering to the renderer (some implementations might render the object directly but this can integrate the underlying rendering API - e.g. OpenGL or DirectX too tightly and rigidly - it is better to separate the scene graph and renderer systems as this promotes good OOP style and extensibility[citation needed]).

In order to dispatch differently for different node types several different approaches can be taken, each have pros and cons and are widely disputed among programmers arguing which is best.

In Object-Oriented languages such as C++ this can easily be achieved by virtual functions, the node base class has virtual functions for every operation that can be performed on the nodes. This is simple to do but prevents the addition of new operations by other programmers that don't have access to the source.

Alternatively the visitor pattern can be used - this is relatively simple and faster than virtual functions where the operation to be performed is decided by multiple dispatch. This has a similar disadvantage in that it is similarly difficult to add new node types.

Other techniques involve the use of RTTI (Run-Time Type Information). The operation can be realised as a class which is passed the current node, it then queries the nodes type (RTTI) and looks up the correct operation in an array of callbacks or functors. This requires that at initialisation the user/system registers functors/callbacks with the different operations so they can be looked up in the array. This system offers massive flexibility, speed and extensibility of new nodes and operations.

Variations on these techniques exist and new methods can offer added benefits - one alternative is scene graph rebuilding where the scene graph is rebuilt for each of the operations performed, this however can be very slow but produces a highly optimised scene graph. This demonstrates that a good scene graph implementation depends heavily on the application in which it is used.

Traversals

Traversals are the key to the power of applying operations to scene graphs. A traversal generally consists of starting at some arbitrary node (often the root of the scene graph), applying the operation(s) (often the updating and rendering operations are applied one after the other), and recursively moving down the scene graph(tree) to the child nodes, until a leaf node is reached. At this point many scene graphs then traverse back up the tree, possibly applying a similar operation. Rendering is an example: While recursively traversing down the scene graph hierarchy the operation(s) applies a PreRender operation. Once reaching a leaf node, it begins traversing back up the tree, applying a PostRender operation. This nicely allows certain nodes to push a state for child nodes, and to pop the state afterwards.

Some scene graph operations are actually more efficient when nodes are traversed in a different order - this is where some systems implement scene graph rebuilding to reorder the scene graph into an easier to parse format or tree.

For example:

In 2D cases, scene graphs typically render themselves by starting at the tree's root node and then recursively drawing the child nodes. The tree's leaves represent the most foreground objects. Since drawing proceeds from back to front with closer objects simply overwriting farther ones, the process is known as employing the Painter's algorithm. In 3D systems, which often employ depth buffers, it is more efficient to draw the closest objects first, since farther objects often need only be depth-tested instead of actually rendered, because they are occluded by nearer objects.

Scene graph and bounding volume hierarchies (BVHs)

Bounding Volume Hierarchies (BVHs) are useful for numerous tasks - including efficient culling and speeding up collision detection between objects. A BVH is a spatial structure but doesn't have to partition the geometry (see spatial partitioning, below).

A BVH is a tree of bounding volumes (often spheres, axis-aligned bounding boxes or/and oriented bounding boxes). At the bottom of the hierarchy the size of the volume is just large enough to encompass a single object tightly (or possibly even

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值