Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OpenGL深度缓冲区具有较短的范围_Java_Opengl_Lwjgl - Fatal编程技术网

Java OpenGL深度缓冲区具有较短的范围

Java OpenGL深度缓冲区具有较短的范围,java,opengl,lwjgl,Java,Opengl,Lwjgl,对于“OpenGL深度缓冲区有短距离”我并不是说远平面太近,这是深度缓冲区作为纹理的问题。如果我看一下缓冲区,它只显示非常接近的对象。我不知道如何更好地解释,只是看看图片 在右上角可以看到深度缓冲区。 可在此处找到图像: 正如你所看到的,我必须非常靠近才能看到深度缓冲区中的黑暗 以下是为FBO创建深度缓冲区的代码: 对于深度纹理: depthTexture = GL11.glGenTextures(); GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTe

对于“OpenGL深度缓冲区有短距离”我并不是说远平面太近,这是深度缓冲区作为纹理的问题。如果我看一下缓冲区,它只显示非常接近的对象。我不知道如何更好地解释,只是看看图片

在右上角可以看到深度缓冲区。 可在此处找到图像:

正如你所看到的,我必须非常靠近才能看到深度缓冲区中的黑暗

以下是为FBO创建深度缓冲区的代码:

对于深度纹理:

depthTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT24, width, height, 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0);
对于深度缓冲区:

depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER, multisampleing, GL14.GL_DEPTH_COMPONENT24, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, depthBuffer);
z_eye(z_win) = 1001/(1000*z_win -1001)
z_eye(0.5) = -1.99800399
您可以忽略GLXX。在OpenGL方法的开头

如果你需要更多的代码,请告诉我

正如你所看到的,我必须非常靠近才能看到深度缓冲区中的黑暗

这就是双曲线深度缓冲区的工作原理

让我们看一下投影矩阵(我使用的是经典的OpenGL约定,相机在眼睛空间中沿
-z
观看,投影矩阵从右手空间翻转到左手空间):

(符号符号只是一些我们不需要关心的数字)

当你将这个矩阵乘以某个眼睛空间向量
(x_-eye,y_-eye,z_-eye,1)
,你将得到

x_clip = ...
y_clip = ....
z_clip =  [-(f+n)/(f-n) ] *z_eye + [-2*f*n/(f-n)] * 1
w_clip = -z_eye
在透视图除以
w_clip
后,我们得到了归一化设备坐标(ndc)中的
z
值:

最后,应用
gldeptrange
到达窗口空间
z
。默认值是从[-1,1]到[0,1],所以让我们在这里这样做:

z_win = 0.5 * z_ndc + 0.5 = 0.5*(f+n)/(f-n)  + f*n/[(f-n)*z_eye] + 0.5
这显然是
z_-eye
的功能,也是
f
n
的功能。假设您使用的是距离为1的近平面和距离为1001的远平面,因此这将计算为:

z_win(z_eye) = 1002/2000 + 1001/(1000 *z_eye) + 0.5 = 1001/1000 + 1001/(1000 * z_eye)
那么,让我们看看我们目前得到了什么:

z_win(-1) = 0.  a point on the near plane ends up as 0 in the depth buffer
z_win(-1001) = 1.  a point on the far plane ends up as 1 in the depth buffer
这不应该让我们感到惊讶,因为这是根据结构。但在这两者之间的几点会发生什么呢

z_win(-50)  = 1001/1000 - 1001/50000  = 0.98098
z_win(-100) = 1001/1000 - 1001/100000 = 0.99099
z_win(-250) = 1001/1000 - 1001/250000 = 0.996996
z_win(-500) = 1001/1000 - 1001/500000 = 0.998998
z_win(-750) = 1001/1000 - 1001/750000 = 0.999665333
因此,正如您所看到的,任何距离眼睛空间超过100个单位的对象都将以深度缓冲值>0.99结束

换言之,我们可以计算一个点的眼睛空间z,该点在深度缓冲区中的值为0.5:

depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER, multisampleing, GL14.GL_DEPTH_COMPONENT24, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, depthBuffer);
z_eye(z_win) = 1001/(1000*z_win -1001)
z_eye(0.5) = -1.99800399
是的,这是正确的,当截锥体距离为1到1001个单位时,只有相机前面1到2个单位的范围将映射到深度缓冲区范围的前半部分,之后的998个单位将填充到下半部分

因此,如果您试图将深度缓冲区可视化为颜色,那么除了最近的部分之外,您什么也看不到。对于8位颜色,高于254/255=.996的所有内容都将完全饱和(在我的示例中为~200个单位),即使低于该值,差异也将非常微小,几乎看不到


如果你只想可视化深度缓冲区,你应该反转双曲线失真,并可视化线性(=眼睛空间)深度。

我猜你的颜色值在某个点被钳制。谢谢你的回答,这解释了很多。我使用此代码反转失真:r=(2*近平面)/(远平面+近平面-纹理2d(depthTexture,texCoord).r*(远平面-近平面));r是深度。它工作得很好。