0
我正在使用Java OpenGL(JOGL 2.x,由Git源構建)。我使用顏色和深度附件將場景渲染爲幀緩衝區對象。我想將[0,1]深度緩衝區值轉換爲世界空間距離。我的深度附件被定義如下:將OpenGL深度緩衝區轉換爲相機的世界空間z距離?
private void setupDepthFBOs(GL2 gl,
int width,
int height,
int[] frameBufferIds,
int[] colorBufferIds,
int[] depthBufferIds) {
// based on
// http://www.java2s.com/Code/Java/Advanced-Graphics/BloomOpenGL.htm
// generate a framebuffer object
gl.glGenFramebuffers(1, frameBufferIds, 0);
// bind the framebuffer
gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, frameBufferIds[0]);
// generate a texture in memory
gl.glGenTextures(1, colorBufferIds,0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, colorBufferIds[0]);
// this will be an RGBA texture (4 bpp) with width, height..
gl.glTexImage2D(GL2.GL_TEXTURE_2D, // target texture type
0, // mipmap LOD level
GL2.GL_RGBA8, // internal pixel format
width, // width of generated image
height, // height of generated image
0, // border of image
GL2.GL_RGBA, // external pixel format
GL2.GL_UNSIGNED_BYTE, // datatype for each value
null); // buffer to store the texture in memory
// set some texture parameters?
gl.glTexParameteri(GL.GL_TEXTURE_2D,
GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
// use the texture we just created in the framebuffer we just created
gl.glFramebufferTexture2D(
GL2.GL_FRAMEBUFFER, // target texture type
GL.GL_COLOR_ATTACHMENT0, // attachment point
GL.GL_TEXTURE_2D, // texture target type
colorBufferIds[0], // on-gpu id for texture
0); // mipmap lod level
gl.glGenTextures(1,depthBufferIds,0);
gl.glBindTexture(GL.GL_TEXTURE_2D,depthBufferIds[0]);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, // target texture type
0, // mipmap LOD level
GL2.GL_DEPTH_COMPONENT24, // internal pixel format
//GL2.GL_DEPTH_COMPONENT
width, // width of generated image
height, // height of generated image
0, // border of image
GL2.GL_DEPTH_COMPONENT, // external pixel format
GL2.GL_UNSIGNED_INT, // datatype for each value
null); // buffer to store the texture in memory
gl.glTexParameteri(GL.GL_TEXTURE_2D,
GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D,
GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D,
GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL.GL_TEXTURE_2D,
GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
GL.GL_DEPTH_ATTACHMENT,
GL.GL_TEXTURE_2D,
depthBufferIds[0],0);
gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
int status = gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER);
if (status == GL2.GL_FRAMEBUFFER_COMPLETE) {
gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);
} else {
throw new IllegalStateException("Frame Buffer Object not created. Status was: " + status);
}
}
這成功地創建了一個深度緩衝器,其中我可以讀作爲紋理和渲染到屏幕上,或作爲輸入使用着色器(我的意最終使用情況)。
在幾天前的IRC討論後,我提出了下面的公式,將投影矩陣(這裏表示爲p)和深度緩衝值與到世界空間屏幕上每個點的距離相關聯的公式:
Z =(p_33)/(p_34 +深度)
(注:我的投影矩陣/眼設置了尋找在Z +方向)
這產生幾乎理智z值,但與場景中已知點的距離與此方程返回的值之間存在明顯的誤差範圍。
任何想法,我可能會在這裏做錯嗎?
請說明如何用實際值設置投影矩陣。另外,您確定要「世界空間」z距離而不是「眼睛空間」z距離嗎?後者通常對你正在做的事情更有意義。 – bernie