optimization - 剪辑发生在渲染的哪个阶段?

标签 optimization opengl

我有一些我正在尝试优化的 OpenGL 绘图代码。它目前正在测试所有绘图对象的客户端可见性,然后再决定是否将渲染数据发送到 OpenGL。 (这比听起来容易。它正在绘制一个 2D 场景,因此剪辑很简单:只需针对视口(viewport)矩形的当前坐标进行测试。)

我突然想到,通过将整个场景传递给 OpenGL 并让 GPU 处理剪辑,可以大大简化整个模型。但有时总数可能非常非常复杂,总共涉及多达 100,000 个 Sprite ,其中大部分永远不会被渲染,因为它们是离机的,我不想以简单的名义最终降低帧率。

我使用的是 OpenGL 2.0,我有一个非常简单的顶点着色器和一个更复杂的片段着色器。是否有任何保证表明,如果顶点着色器运行并确定多边形的所有顶点的坐标完全在相机外,那么剪裁测试将在该处和片段着色器之间的某处应用,并防止片段着色器运行对于那个多边形?如果是这样,这是自动的还是我需要做些什么来启用它?我在网上四处寻找这方面的信息,但我没有找到任何确凿的信息......

最佳答案

裁剪发生在 NDC 空间之前和之后的顶点变换阶段之后; 剪辑平面在剪辑空间中应用,视口(viewport)剪辑在 NDC 空间中完成。这是光栅化之前的一步。裁剪意味着,通过在可见性边界处插入新顶点或丢弃视口(viewport)外的片段来“裁剪”仅部分可见的面。您的意思通常称为剔除。完全在视口(viewport)之外的面会被剔除,就像剪裁一样在同一阶段。

从性能的角度来看,最好的代码是从不执行的代码,最好的数据是从不访问的数据。因此,在您的情况下,发送使 GPU 处理大量顶点的单个绘图调用显然会减轻 CPU 的负载,但会消耗 GPU 处理能力。在发送绘图命令之前剔除这些顶点会消耗 CPU 功率,但会减轻 GPU 的负载。目标是找到正确的平衡。如果顶点的数量很少,一个简单的蛮力方法(只是渲染整个事物)可能很容易胜过其他方案。

但是,使用简单而有效的数据管理方案可以大大提高两端的性能。例如,像 Kd 树这样的空间分割结构很容易构建(您不必平衡它)。将顶点排序到 Kd 树中,如果靠近根的一个分支完全在视口(viewport)之外,则可以省略(剔除)树的大部分。准备绘制一个帧,您遍历树的可见部分,构建要绘制的顶点列表,然后将此列表传递给渲染命令。平均可以在 O(n log n) 时间内遍历 Kd 树。

关于optimization - 剪辑发生在渲染的哪个阶段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7959838/

相关文章:

c++ - 单击鼠标时不需要的 SDL_QUIT 事件

c++ - Qt QOpenGLWidget glClearColor 无法正常运行

sql - 如何优化sql查询?好像distinct很慢?

optimization - 小于 "add esp, 4"的指令

numpy - 为什么 np.einsum 中的优化参数默认为 False?

c++ - 如何使用 http ://www. opengl-tutorial.org/正确学习 OpenGL?

opengl - 在着色器中访问时,OpenGL如何决定使用MAG_FILTER和MIN_Filter?

javascript - 有没有更好的方法来编写这个显示/隐藏 JQuery 代码?

c - 给定数组中两个元素之间的最小距离

java - 使用 JOGL 截图