我一直试图找到一种方法来读取特定鼠标坐标(x,y)的深度值。使用opengl 4.x在win10上一切正常,但不适用于opengl es 3.x
我的方法:
后续的方法就足够了,但不幸的是,在win10上也是不准确的,但为什么呢?
#version 420
uniform vec2 screenXy;
uniform vec2 screenSize;
out vec4 fragColor;
void main(void) {
if((int(gl_FragCoord.x) == int(screenXy.x)) && ((int(screenSize.y) - int(gl_FragCoord.y)) == int(screenXy.y))) {
fragColor.r = gl_FragCoord.z;
} else {
fragColor = vec4(1, 1, 1, 1.0);
}
}
我将鼠标xy坐标提交给fragementshader(screenXy)。如果单击的像素在行中,我会在颜色缓冲区中写入深度值。这是有效的,但是值gl_FragCoord.z和深度缓冲区中的值并不完全相同(我知道深度缓冲区中的这个值是正确的)。虽然gl_FragCoord.z和深度缓冲区值是浮点数,所以我认为是32位。
GLfloat zd; // from depth buffer
GLfloat zc[4]; // from color buffer
m_func->glReadPixels(xy.x(), m_pFbo->height() - xy.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zd);
m_func->glReadPixels(xy.x(), m_pFbo->height() - xy.y(), 1, 1, GL_RGBA, GL_FLOAT, zc);
原因:
也许有人可以帮助我并解决问题,因为我找不到任何其他解释?
这里有一些测量值:
zc 0.984314
zd 0.985363
zc 0.552941
zd 0.554653
zc 1 -> extremly critical
zd 0.999181
答案 0 :(得分:2)
Since 0.984314 * 255.0 is exactly 251.0, I assume the internal format of the color plane is GL_RGBA8
. That means there is 1 byte for each color channel and zc
can only have 256 different values, from 0.0 to 1.0 in steps of 1/256.
If it is supported by the OpenGL ES version which you use, then you can change the format of the render buffer storage (e,g. GL_R32F
- only red color channel, but 32 bit floating point).
Or you can encode the depth to the 4 channels of the 4 * 8 bit color plane:
vec4 PackDepth( in float depth )
{
depth *= (256.0*256.0*256.0 - 1.0) / (256.0*256.0*256.0);
vec4 encode = fract( depth * vec4(1.0, 256.0, 256.0*256.0, 256.0*256.0*256.0) );
return vec4( encode.xyz - encode.yzw / 256.0, encode.w ) + 1.0/512.0;
}
....
fragColor = PackDepth(gl_FragCoord.z);
And you can decode it after reading the value:
GLfloat zc[4]; // from color buffer
m_func->glReadPixels(xy.x(), m_pFbo->height() - xy.y(), 1, 1, GL_RGBA, GL_FLOAT, zc);
float depth = zc[0] + zc[1]/256.0 + zc[2]/(256.0*256.0) + zc[3]/(256.0*256.0*256.0);
depth = depth * (255.0f/256.0f) * (256.0*256.0*256.0) / (256.0*256.0*256.0 - 1.0);
答案 1 :(得分:0)
我仍然不确定gl_FragCoord.z是否与深度测试后的深度缓冲区相同。使用计数器,您可以进行查询
<script>
export default {
name: "DropdownTemplate",
props: ["header"],
template: `<div>
<div><h3>Sports 1</h3></div>
</div>`,
data() {
return {};
}
};
</script>
<style scoped>
h3 {
padding-left: 10px;
}
</style>
基本上是深度测试的作用。但是如何将gl_FragCoord.z_last存储为静态?有没有办法在openGL 3.x中读取深度值无损?根据solidpixel,只有来自opengl 3.2的浮动帧缓冲。
答案 2 :(得分:0)
深度缓冲区中的值似乎与gl_FragCoord.z不完全相同。我认为以下示例演示了它。
#version 420
uniform vec4 color;
uniform vec2 screenXy;
uniform vec2 screenSize;
in vec2 vBC;
out vec4 fragColor;
void main(void) {
fragColor.r = gl_FragCoord.z;
}
C ++
GLfloat zd;
GLubyte zc[4];
m_func->glReadPixels(xy.x(), m_pFbo->height() - xy.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zd);
m_func->glReadPixels(xy.x(), m_pFbo->height() - xy.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, zc);
数据: zc0 = 255(来自gl_FragCoord.z); zd = 0.996561(来自深度缓冲区)
但它应该是254,因为0.996561 * 255 = 254.123055。