Mas*_*ler 3 opengl optimization
我有一些正在尝试优化的 OpenGL 绘图代码。目前,它正在测试所有绘图对象的客户端可见性,然后再决定是否将渲染数据发送到 OpenGL。(这比听起来容易。它正在绘制 2D 场景,因此剪切很简单:只需根据视口矩形的当前坐标进行测试。)
我突然想到,通过将整个场景传递给 OpenGL 并让 GPU 负责裁剪,可以大大简化整个模型。但有时总数可能非常非常复杂,总共涉及多达 100,000 个精灵,其中大多数永远不会渲染,因为它们不在摄像机之外,而且我不希望最终以简单的名义杀死帧速率。
我使用的是 OpenGL 2.0,并且有一个非常简单的顶点着色器和一个更复杂的片段着色器。是否有任何保证表明,如果顶点着色器运行并确定多边形所有顶点完全离开相机的坐标,则将在顶点着色器和片段着色器之间的某个位置应用裁剪测试,并阻止片段着色器运行对于那个多边形?如果是这样,这是自动的还是我需要做一些事情才能启用它?我在网上查找了这方面的信息,但没有找到任何结论性的信息......
裁剪发生在 NDC 空间前后的顶点变换阶段之后;剪裁平面应用于剪裁空间,视口剪裁在 NDC 空间中完成。这是光栅化之前的一步。剪切意味着,通过在可见性边界插入新顶点或丢弃视口之外的片段,“剪切”仅部分可见的面。你的意思通常被称为剔除。完全在视口之外的面将被剔除,在与剪切相同的阶段。
从性能的角度来看,最好的代码是从未执行过的代码,最好的数据是从未访问过的数据。因此,在您的情况下,发送单个绘图调用使 GPU 处理大量顶点显然可以减轻 CPU 的负载,但会消耗 GPU 处理能力。在发送绘图命令之前剔除这些顶点会消耗 CPU 电量,但会减轻 GPU 的负载。目标是找到适当的平衡。如果顶点数量较少,则简单的强力方法(只需渲染整个事物)可能会轻松优于其他方案。
然而,使用简单而有效的数据管理方案可以极大地提高两端的性能。例如,像 Kd 树这样的空间细分结构很容易构建(您不必平衡它)。将顶点排序到 Kd 树中时,如果靠近根的一个分支完全在视口之外,则可以忽略(剔除)树的大部分。准备绘制帧时,您将迭代树的可见部分,构建要绘制的顶点列表,然后将此列表传递给渲染命令。平均可以在 O(n log n) 时间内遍历完 Kd 棵树。