避免使用OpenGL顶点数组在屏幕外绘图

Puc*_*tek 3 opengl performance

我有一个大的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) ;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Sig*_*erm 9

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

所需知识:

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

这是基本的3D内容,可以在网上的大量教程中找到.谷歌"矩阵常见问题",例如,gamasutra 7年前也有aabb/obb教程.

- 编辑 -

弄清楚3D空间中的坐标是否可见是部分聊天逃避了我.好吧,回到记事本和一些教程

平面可以由point(p)和normal(n)定义. p是平面上的一个点,n是一个垂直于平面的矢量.

给定点p1,您可以通过执行简单计算来确定此点是位于平面上方,平面上还是下方.

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

Frustrum是一个"可见体积",由4个在相机原点相交的平面定义.有没有在3D编辑器中看到"相机锥"?如果可视化,这就是截头形状的样子.

现在,让我们假设所有那些"截头"平面法线(平面法线n,还记得吗?)指向截头体外面.

现在,您有一个要测试的对象.如果该对象的边界框的所有点都在"上方"(或"外部"),即使对于一个截头体平面,对象也是不可见的,因为它不会使截头体变形.这是基于分离轴定理.即使您使用对象的点而不是边界框,这也将起作用.

这应该足以让你开始.你可以谷歌休息.谷歌的教程和3D相关的东西 - 这些主题在过去10年被讨论死亡(主要是由想要的游戏开发者和初学者),应该有关于这个主题的信息海洋.