performance - 避免使用 OpenGL 顶点数组在屏幕外绘制

标签 performance opengl

我有一个大型 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 速率与查看整个屏幕时的 FPS 速率相同,因此 OpenGL 似乎仍然绘制了所有落在屏幕外的顶点(或者至少在管道中进行了足够多的处理,与绘制没有区别他们在时间成本方面)。

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

最佳答案

计算边界框 ( axis-aligned (AABB) or oriented (OBB) ) 并检查 if it is visible .如果它不可见,请不要绘制对象。

所需知识:

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

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

    - 编辑 -

    Figuring out if a coordinate in 3D space is visible is the part chat escapes me. Well, back to notepad and a few tutorials



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

    给定点 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 > 0 p1 在平面上方,如果 dist < 0 ,它在平面下方,如果dist == 0它在飞机上。

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

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

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

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

    关于performance - 避免使用 OpenGL 顶点数组在屏幕外绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18308537/

    相关文章:

    javascript - HTML 大小对我的 Js 有多重要(对我的页面加载时间更重要)

    php - set_time_limit 不起作用

    performance - OpenGL/DirectX : How does Mipmapping improve performance?

    c - OpenGL vbo 上传不一致

    php - 自定义 preg_replace 函数的任何更有效的方法?

    java - 将节点连接到树中的下一个兄弟节点

    c++ - 具有多个着色器程序的 OpenGL 多纹理

    c - 在OpenGL中变换后获取顶点?

    c - 删除 GLUT 函数调用

    opengl - 查看玩家正在看什么 "block"