游戏引擎:什么是场景图?

时间:2011-03-15 23:29:41

标签: c++ graph scenegraph

我开始阅读维基百科上的资料,但我仍然觉得我并不真正理解场景图的工作原理以及它如何为游戏带来好处。

  • 游戏引擎开发环境中的场景图是什么?
  • 为什么我要为我的2D游戏引擎实现一个?
  • 场景图的使用是否可以替代具有线性实体管理器的传统实体系统?

5 个答案:

答案 0 :(得分:25)

  

游戏中的场景图是什么   引擎开发背景?

嗯,这是一些代码,可以在游戏空间中对游戏对象进行主动排序,从而轻松快速查找哪些对象位于游戏空间中的某个点。

这样,很容易:

  1. 快速找到相机视图中的对象(并仅将它们发送到图形卡,使渲染速度非常快)。
  2. 快速找到玩家附近的物品(并仅对那些物品进行碰撞检查)
  3. 等等。它是关于允许在太空中快速搜索。它被称为“空间分区”。这是关于分而治之的。

      

    为什么我要实现一个   我的2D游戏引擎?

    这取决于游戏类型,更准确地说取决于游戏空间的结构。

    例如,像塞尔达这样的游戏如果足够快以测试屏幕中所有对象之间的碰撞,就不需要这样的技术。然而,它很容易变得非常慢,所以大多数时候你至少设置一个场景图(或任何类型的空间分区),至少知道所有移动物体周围的东西,并仅测试那些物体上的碰撞。

    所以,这取决于。大多数情况下,出于性能原因需要它。但是你的空间分区的实现完全与你的游戏空间结构相关。

      

    是否使用场景图   作为经典实体的替代品   系统与线性实体管理器?

    没有

    无论你管理游戏实体的对象生活是什么方式,空间分区/场景图只是为了让你能够快速搜索太空中的物体,不多也不少。大多数情况下,它将是一个具有一些对象槽的对象,对应于游戏空间的不同部分,并且在那些槽中,它将是这些部分中的对象。 它可以是平的(如2或4中的2D屏幕分隔符),或者它可以是树(如二叉树或四叉树,或任何其他类型的树)或任何其他排序结构,限制您必须的操作数量执行以获取一些与空间相关的信息。

    注意一件事:

    在某些情况下,您甚至需要不同的独立空间分区系统用于不同目的。通常情况下,“场景图”是关于渲染的,因此它的优化方式取决于玩家的观点,其目的是允许快速收集要渲染的对象列表以发送到图形卡。它不适合执行对另一个对象周围的对象的搜索,这使得很难用于精确的碰撞检测,就像使用物理引擎时一样。所以为了帮助你,你可能只是为了物理目的而拥有一个不同的空间分区系统。

    举个例子,我想制作一个“子弹地狱”游戏,其中有很多球,玩家的宇宙飞船必须以非常精确的方式躲闪。为了获得足够的渲染和碰撞检测性能,我需要知道:

    1. 当子弹出现在屏幕空间中时
    2. 当子弹离开屏幕空间时
    3. 当玩家与子弹碰撞时
    4. 当玩家与怪物发生碰撞时
    5. 所以我递归地切割了4个部分的2D屏幕,这给了我一个四叉树。四叉树每次游戏都会更新,因为一切都在不停地移动,所以我必须跟踪四叉树中每个物体(宇宙飞船,子弹,怪物)的位置,以了解哪一个位于屏幕的哪个部分。

      实现1.很简单,只需在系统中输入子弹即可。

      实现2.我在屏幕边框上保留了四叉树中的叶子列表(屏幕的方形部分)。那些叶子包含靠近边界的子弹的ids /指针,所以我只需检查他们是否正在移动以知道我是否可以停止渲染它们并管理碰撞。 (可能有点复杂,但你明白了。)

      要达到3和4.我需要检索玩家宇宙飞船附近的物体。所以首先我得到了玩家宇宙飞船所在的叶子,然后我得到了所有物体。这样我只会测试与玩家宇宙飞船在周围物体上的碰撞,而不是所有物体。 (它有点复杂,但你明白了。)

      这样我就可以确保即使数以千计的子弹不断移动,我的游戏也能顺利运行。

      在其他类型的空间结构中,需要其他类型的空间分区。通常情况下,卡丁车/自动游戏将有一个“隧道”场景图,因为视觉上玩家只会看到路上的东西,所以你只需要检查他在路上的位置,以检索“隧道”周围的所有可见物体。

答案 1 :(得分:16)

什么是场景图? A Scene graph包含特定场景的所有几何图形。它们对于表示相对于彼此的翻译,旋转和比例(以及其他affine transformations)对象非常有用。

例如,考虑一个坦克(带有轨道和枪的类型)。您的场景可能有多个坦克,但每个坦克的定向和定位都不同,每个坦克的炮塔都旋转到不同的方位角和不同的炮高。您可以在遍历场景图时正确定位仿射变换以正确定位,而不是确切地确定每个坦克应该如何定位喷枪。它使这些事情的计算变得更加容易。

2D场景图:如果您的内容足够复杂并且您的对象具有多个未严格固定到较大主体的子组件,则使用2D场景图可能很有用。否则,正如其他人所提到的那样,这可能是过度的。 2D中仿射变换的复杂性比3D情况要小得多。

线性实体经理:我不清楚linear entity manager究竟是什么意思,但是如果你只想跟踪场景中的位置,如果场景中各种物体或子物体之间存在高度的空间依赖性,那么场景图可以使事情变得更容易。

答案 2 :(得分:3)

场景图是一种组织环境中所有对象的方法。通常需要注意组织数据以进行有效渲染。如果您愿意,图形或树可以显示子对象的所有权。例如,在最高层可能有一个城市物体,在它下面会有许多建筑物,在那些可能是墙壁,家具......

但大多数情况下,这些仅用于3D场景。我建议不要选择2D场景那么复杂的东西。

答案 3 :(得分:3)

网上似乎有很多不同的哲学,关于场景图的反应是什么。人们往往会投入很多不同的东西,如几何,相机,光源,游戏触发器等。

一般情况下,我会将场景图形描述为场景的描述,并由包含场景中存在的实体的单个或多个数据结构组成。这些数据结构可以是任何类型(数组,树,Composite pattern等),并且可以描述实体的任何属性或场景中实体之间的任何关系。 这些实体可以是从实体可绘制对象到碰撞网格,相机和光源的任何东西。 到目前为止,我看到的唯一真正限制是人们建议保留游戏特定组件(如游戏触发器),以防止以后出现依赖问题。这些事情必须被抽象出来,比如“LogicEntity”,“InvisibleEntity”或者只是“Entity”。

以下是场景图中的一些常见用法和数据结构。

父/子关系

在游戏或引擎中使用场景图的方式是描述具有位置的任何东西之间的父/子关系,无论是实体对象,相机还是其他任何东西。这种关系意味着任何儿童的地位,规模和方向都与其父母的地位,规模和方向相关。这将允许您使相机跟随播放器或使灯光跟随手电筒对象。它还可以让你制作像太阳系这样的东西,你可以在其中描述行星相对于太阳的位置以及卫星相对于它们的行星的位置,如果你正在做的那样。

您的游戏/引擎中某些系统特有的内容也可以存储在场景图中。例如,作为物理引擎的一部分,您可能已为固体对象定义了简单的碰撞网格,这些对象可能具有太复杂的几何体以测试碰撞。您可以在场景图中放置这些碰撞网格(我确定它们有另一个名字,但我忘了它:P)并让它们跟随它们建模的对象。

空间的分割

场景图中另一种可能的数据结构是space-partitioning的某种形式,如其他答案中所述。这将允许您在场景上执行快速查询,例如剪切不在视锥体中的任何对象,或者有效地过滤掉需要冲突检查的对象。您还可以允许客户端代码(如果您正在编写引擎)以执行任何目的的自定义查询。这样客户端代码就不必维护自己的空间分区结构。

我希望我能为您和其他读者提供一些关于如何使用场景图以及您可以放入其中的内容的想法。我确信有很多其他方法可以使用场景图,但这些是我想出来的。

答案 4 :(得分:2)

实际上,视频游戏中的场景对象很少被组织成一个图形,当渲染场景时,该图形作为树“行走”。图形系统通常需要渲染一大堆东西,并且这个大数组是线性移动的。

需要几何育儿关系的游戏,例如人们持枪或带炮塔的坦克,在图形系统之外根据需要定义和实施这些关系。这些关系往往只有一个深度,因此几乎不需要任意深度的树结构。