【问题标题】:Using depth buffer for layering 2D sprites使用深度缓冲区对 2D 精灵进行分层
【发布时间】:2014-07-27 01:16:09
【问题描述】:

我正在使用 OpenGL 制作 2D 游戏。我想做这样的绘图,首先我将要绘制的所有对象的顶点数据复制到 VBO(每个纹理/着色器一个 VBO),然后在单独的绘图调用中绘制每个 VBO。这似乎是一个好主意,直​​到我意识到它会打乱绘图顺序 - 绘图调用不一定按照将对象加载到 VBO 中的顺序。我想过使用深度缓冲区对项目进行排序——每个要绘制的新对象的 Z 位置都会稍高一些。问题是,我应该增加多少才不会遇到任何问题? AFAIK,可能有两种问题 - 如果我让它太大,那么我可以在单个帧中绘制的对象数量有限,如果我让它太小,深度缓冲区的精度损失可能会重叠的图像以错误的顺序绘制。总结一下:

1) 我的正交投影的前后值应该是多少? 0比1? -1比1? 1比2?有关系吗?

2) 如果我使用 's nextafter() 来增加 Z 位置,我会遇到什么样的麻烦? OpenGL 和深度缓冲区如何对低于标准的浮点数做出反应?如果我从 std::numeric_limits::min() 开始,到 1 结束,还有什么需要担心的吗?

【问题讨论】:

  • nearValfarVal 的值非常重要。默认情况下,深度范围是 [0,1] 并且深度缓冲区是定点的,所以如果你使用 nearVal=0.0farVal=1.0 为例,那么您可以区分的最小深度是 1.0/(256.0*256.0)(16 位)。这是一个非常尴尬的数字并且会受到浮点恶作剧的影响,因此我建议您改为设置 farVal 以便将深度缓冲区划分为整数。这意味着您希望nearValfarVal 之间的范围等于您的深度缓冲区可以表示的整数值的数量。
  • 如果使用混合,则需要手动排序,注意那个
  • @AndonM.Coleman 我觉得这个数字没什么尴尬。
  • @paulm 我没有在精灵之间进行 Alpha 混合。

标签: c++ opengl floating-point depth-buffer


【解决方案1】:

首先,您需要知道深度缓冲区的位深度。通常深度缓冲区是定点的,16 位、24 位或 32 位。

给定一个定点深度缓冲区和默认深度范围 [0,1],您可以使用正交投影使每个整数值表示一个唯一可区分的深度nearVal 的矩阵 0.0 和:

  • 16 位:   farVal = 65535.0
  • 24 位:   farVal = 16777215.0      // 最常见的配置
  • 32 位:   farVal = 4294967295.0

然后,您可以将分层精灵分配到farVal+1-许多不同的深度(始终使用整数值作为精灵深度并以 0 开头)并且不用担心深度缓冲区无法区分图层。换句话说,深度缓冲区的精度将决定您可以拥有的最大层数。

【讨论】:

  • 好的,但是如何获得深度缓冲区精度(即字节数)?
  • 您可以执行以下操作:GLuint depth_bits; glGetIntegerv (GL_DEPTH_BITS, &depth_bits);。至于您如何实际请求一定的深度缓冲区精度,这取决于您使用的框架。但这是在 OpenGL 上下文创建时完成的(除非您使用 FBO,但这只会使事情变得比现在需要的更复杂)。如果您没有明确请求特定数量,许多框架默认为 24​​ 位。
  • “这只是让事情变得比现在需要的更复杂”你是想侮辱我吗?无论如何,非常感谢。
  • @Xirdus:不,一点也不。我的意思是我试图避免在这里讨论任何额外的跑腿工作。设置 FBO 会使事情变得不必要地复杂化,但它避免任何与设置 default 帧缓冲区深度缓冲区的精度相关的特定于平台的过程.
  • FBO 并不难,你知道的。此外,您查询 GL_DEPTH_BITS 的方法似乎已被弃用。但这对我来说不是问题,因为 GLFW 允许明确指定它,并且记录了默认值为 24。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-14
  • 1970-01-01
  • 2020-07-13
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多