我有一个大的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似乎绘制了所有那些落在屏幕之外的顶点(或者至少在管道中与它们一起进展得足够远,因为它们与绘图没有区别他们在时间成本方面)。
有没有办法测试特定顶点数组的内容是否落在屏幕之外,所以我可以避免绘制它?
答案 0 :(得分:9)
计算边界框({{3}})并检查axis-aligned (AABB) or oriented (OBB)。如果它不可见,请不要绘制对象。
所需知识:
ax + by + cz + d = 0
)这是基本的3D内容,可以在网上的大量教程中找到。谷歌“矩阵常见问题”,例如,gamasutra 7年前也有aabb / obb教程。
- 编辑 -
确定3D空间中的坐标是否可见是部分聊天逃脱了我。好吧,回到记事本和一些教程
平面可以由点(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
位于平面上。
Frustrum是一个“可见体积”,由4个在相机原点相交的平面定义。曾经在3D编辑器中看到过if it is visible吗?如果想象的话,那就是截头形状。
现在,让我们假设对于所有那些“截头”平面法线(平面法线,n
,还记得吗?)指向截头外面。
现在,您有一个要测试的对象。如果该对象的边界框的所有点都在“上方”(或“外部”),即使对于一个截头体平面,对象也是不可见的,因为它不会使截头体变形。这是基于分离轴定理。即使您使用对象的点而不是边界框,这也会起作用。
这应该足以让你入门。你可以谷歌休息。谷歌的教程和3D相关的东西 - 这些话题在过去10年中被讨论过死亡(主要是由想要的游戏开发者和初学者),应该有关于这个主题的信息海洋。