【问题标题】:opengl depth buffer slow when points have same depth当点具有相同的深度时,opengl深度缓冲区很慢
【发布时间】:2013-02-03 15:43:40
【问题描述】:

我正在制作一个 2d 游戏,其中涉及在屏幕上绘制大量重叠的四边形。什么在前面,什么都不重要。

如果我使用从 0 向上的 z 值绘制每个四边形并设置 glDepthFunc(GL_LESS),我会如您预期的那样获得相当不错的速度提升。 这是为了避免必须绘制完全隐藏或部分隐藏在其他四边形后面的四边形。 所以我使用类似的东西绘制四边形:

float small = (float(1)/1000000);
for (int iii = 0; iii < 100000; iii++) {
    freeSpace = bullets[iii]->draw(opengl, freeSpace, iii*small);
}

但是,由于我没有将 z 值用于实际深度,所以我似乎应该可以去:

for (int iii = 0; iii < 100000; iii++) {
    freeSpace = bullets[iii]->draw(opengl, freeSpace, 0.0f);
}

或者只是将 z 值 0.0f 编码到着色器中。 (第三个参数是 z 值,最终在着色器中设置为 gl_position 不变。)

奇怪的是,第二种方法(我每次都将 z 值设置为 0.0f)最终得到的帧率几乎不到前者的一半。

这是为什么?他们都使用 glDepthFunc(GL_LESS) 和

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 100000*(2*3));

同样如此。我认为如果每次将 z 设置为 0.0f 会更快。为什么不是?

【问题讨论】:

  • 你将深度缓冲区清除到什么值?
  • 否,但它小于 1(这是深度缓冲区被清除的值)。所以这个想法是每个像素只被写入一次。我可以使用 GL_LEQUAL,它的性能仍然很差(数量与 GL_LESS 相同)。我的目标是尝试让深度缓冲区只让每个像素被绘制一次,以降低填充率要求。
  • 深度缓冲区清除为默认值(我从不更改它)。所以我相信它会清除到 1.0f。

标签: performance opengl gpu depth depth-buffer


【解决方案1】:

我不是很肯定,但我的猜测是原语之间 z 值的小增量允许 zcull 硬件工作。这将在片段到达片段着色器之前剔除片段。除了避免片段着色器工作之外,当片段进入深度缓冲区测试时,这种剔除可以比正常的 z 测试更快地发生。

【讨论】:

  • 啊,谢谢。这听起来可能。我在片段着色器中丢弃,所以我相信早期的 zcull 是不可能的。然而,正常的剔除可能确实发生了。奇怪的是,当点具有和 z 值时不会发生这种情况?我该如何解决这个问题?我目前的方法似乎很复杂。我应该使用模板缓冲区还是让顶点着色器以某种方式生成 z 值?不管怎样,谢谢你的回复。
  • 哦,是的,如果您在片段着色器中杀死片段,则无法使用 zcull 硬件,这也会影响其他 z-testing 性能改进。如果您可以避免执行片段着色器终止,您可能会发现性能有显着的改进。
  • 我必须在屏幕上画圆圈,因此这似乎是不可避免的。我正在将纹理绘制到四边形和以太上的圆圈我必须打开混合,这会导致减速或丢弃片段着色器中 alpha 值为 0 的所有像素。还有另一种(更好的)方法吗?我是否认为即使我在片段着色器中丢弃某种 zculling 仍在继续?
  • 我认为基本的答案是——它很复杂,所以没有一个简单的答案。您正在探索不同芯片将以不同方式加速和优化的部分管道。听起来您通常对图形管道中应该发生的事情有一个很好的了解。我建议您尝试一下您的想法并探索设计空间,看看什么最适合您的卡片。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多