3

我有一个大型 3D 场景,所有对象都存储在 OpenGL 顶点数组中,并且每个帧都使用以下内容绘制:

for(int i = 0 ; i < noLists ; ++i)
{
    glVertexPointer(3, GL_FLOAT, 0, vertexArraysList[i] ) ;
    glColorPointer(4, GL_FLOAT, 0, colorArraysList[i] ) ;
    glDrawArrays(GL_QUAD_STRIP, 0, verticesNumber) ;
}

通常,用户首先开始查看整个场景,但很快识别出感兴趣的部分并放大给定区域,因此整个场景的大部分都落在屏幕之外。但是我发现缩放时的 FPS 速率与查看整个屏幕时相同,因此 OpenGL 似乎仍然绘制了所有那些落在屏幕之外的顶点(或者至少在管道中的进展足够远,与绘制没有区别他们在时间成本方面)。

有没有办法测试特定顶点数组的内容是否落在屏幕之外,所以我可以避免绘制它?

4

1 回答 1

9

计算边界框(轴对齐(AABB)或定向(OBB))并检查它是否可见。如果它不可见,请不要绘制对象。

必备知识:

  1. 平面方程 ( ax + by + cz + d = 0)
  2. 点到平面距离计算。
  3. 使用点和法线或使用 3 个点构造平面(方程)。
  4. 将矩阵变换应用于点/向量。
  5. 矢量叉积。

这是可以在网络上的大量教程中找到的基本 3D 内容。谷歌“matrix faq”,比如gamasutra 7年前也有aabb/obb教程。

- 编辑 -

弄清楚 3D 空间中的坐标是否可见是我无法理解的部分。好吧,回到记事本和一些教程

平面可以由点 ( p) 和法线 ( n) 定义。 p是平面上的一点n,是垂直于平面的向量。

给定 point p1,您可以通过执行简单的计算来确定该点是位于平面上方、平面上还是下方。

dist = dot((p1 - p), n), 其中dot是点积 ( dot(a, b) = a.x*b.x + a.y+b.y + a.z*b.z) 如果n是单位长度 ( dot(n, n) == 1) dist 将存储从点到平面的距离。否则,它的标志将指示p1位于何处。如果dist > 0p1 在平面之上,如果dist < 0,它在平面之下,如果dist == 0它在平面上。

Frustrum 是一个“可见体积”,由在相机原点相交的 4 个平面定义。曾经在 3d 编辑器中看到过“相机锥”吗?如果可视化,这就是截锥体的样子。

现在,让我们假设对于所有那些“截锥体”平面法线(平面法线n,,记得吗?)指向截锥体之外。

现在,您有一个要测试的对象。如果此对象边界框的所有点都在“上方”(或“外部”),即使对于一个截锥体平面,对象也是不可见的,因为它不与截锥体相交。这是基于分离轴定理。即使您使用对象的点而不是边界框,这也将起作用。

这应该足以让你开始。你可以谷歌其余的。谷歌上的教程和 3d 相关的东西——这些话题在过去 10 年里被讨论得死死的(主要是想成为游戏开发者和初学者的人),应该有关于这个主题的海量信息。

于 2013-08-19T07:41:23.483 回答