如何使用深度缓冲区来存储索引

Gig*_*igo 5 opengl shader glsl depth-buffer

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

我的计划是由AMD的一些人实现空间哈希算法(链接到pdf).

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

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

我的顶点着色器因此做了类似的事情:

float depth = 2.0 * gl_VertexID / ParticleCount - 1.0;
gl_Position = vec4(flatCoords, depth, 1.0);
Run Code Online (Sandbox Code Playgroud)

这有点工作,但实际存储到绑定到当前帧缓冲区的深度纹理的值会让我感到困惑.我没有完全理解浮点深度缓冲区和整数版本之间的区别,如果我甚至无法输出实数整数,并且从深度纹理读取后,[0..1]无论我设置的是什么内部格式,所有内容似乎都被标准化(DepthComponent24,32,32f).

有人可以给我一些建议如何从这些深度纹理中获取VertexIDs吗?

谢谢

cam*_*ake 2

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

depth_buf_value = 0.5 + 0.5 * gl_Position.z / gl_Position.w;
Run Code Online (Sandbox Code Playgroud)

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

vertex_id = depth_buf_value * ParticleCount
Run Code Online (Sandbox Code Playgroud)

  • 0..1 范围内的浮点值将转换为给定的内部格式。24 位整数格式和浮点格式应该获得相同的精度,因为后者具有 24 位尾数(23+隐式前导位),可用于表示整数而不会丢失位。然而,由于在 OpenGL 中它会经历重新映射部分,因此至少会丢失一位精度。但这仍然留下 23 位具有超过 800 万个不同的值。 (2认同)