【问题标题】:How to use depth buffer to store indices如何使用深度缓冲区来存储索引
【发布时间】:2013-07-26 03:08:14
【问题描述】:

我想以一种稍微不正统的方式使用深度缓冲区,但我对所有标准化、缩放以及那里发生的事情感到非常困惑。

我的计划是由 AMD (link to pdf) 的一些人实施空间散列算法。

tl;dr-version:通过将 3D 顶点离散化为(平面 2D)深度纹理数组,将深度设置为 VertexID,从而加快最近邻搜索。使用深度纹理的原因是正在进行一些智能深度测试,甚至可以按排序顺序获得结果,但这在这里并不重要。

我的问题是VertexID显然是一个整数,范围从0到顶点总数ParticleCount,但是不能直接使用,因为顶点着色器的输出必须归一化为OpenGL 中的 [-1..1)(或 DirectX 中的 [0..1))。

因此,我的顶点着色器会这样做:

float depth = 2.0 * gl_VertexID / ParticleCount - 1.0;
gl_Position = vec4(flatCoords, depth, 1.0);

这是一种工作,但实际存储到绑定到当前帧缓冲区的深度纹理的值让我感到困惑。 我不太明白浮点深度缓冲区和整数版本之间的区别,如果我什至不能输出真正的整数,并且稍后从深度纹理中读取时,一切似乎都归一化为[0..1],无论内部是什么我设置的格式 (DepthComponent24, 32, 32f)。

谁能给我一些建议,如何从这些深度纹理中获取 VertexID?

谢谢

【问题讨论】:

  • "在 OpenGL 中归一化为 [-1..1)(或在 DirectX 中归一化为 [0..1)" 1 在这两种情况下都包含在内。
  • 你说得对,有点疏忽。但是深度测试的默认行为是将深度缓冲区清除为 1 并使用“小于”比较,因此所有深度为 1 的点都会被剔除。

标签: opengl glsl shader depth-buffer


【解决方案1】:

在透视分割被裁剪为 [-1,1] 后,OpenGL 中顶点着色器的输出,这意味着 gl_Position.z/gl_Position.w 必须在该范围内。 但是,实际存储在深度缓冲区中的深度值会使用当前深度范围 (glDepthRange) 值重新映射到 0..1 范围。默认情况下,深度范围为 0..1,即

depth_buf_value = 0.5 + 0.5 * gl_Position.z / gl_Position.w;

因此,在您的情况下,深度缓冲区最终包含 float(gl_VertexID) / ParticleCount 的值,因此:

vertex_id = depth_buf_value * ParticleCount

【讨论】:

  • 好的,这证实了我尝试做的事情应该有效,但它没有。我会尽快回到这个项目以使其正常工作。
  • 我的另一个想法是:精度怎么样?用于深度缓冲区的内部格式让我有点困惑。它像浮点数一样处理,但存储为规范化的 int?这会影响可以表示的范围吗? ParticleCount 很可能是一百万或更多,我必须能够可靠地从深度缓冲区中恢复粒子索引。
  • 0..1 范围内的浮点值被转换为给定的内部格式。您应该使用 24 位整数格式和浮点格式获得相同的精度,因为后者具有 24 位尾数(23+隐式前导位),可用于表示整数而不会丢失位。但是,由于在 OpenGL 中它会经过重新映射部分,因此至少会丢失一点精度。但这仍然留下 23 位具有 >8 百万个不同值。
猜你喜欢
  • 2012-04-12
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
相关资源
最近更新 更多