我有一个大型 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
) 这是基本的 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/