2017-05-31 58 views
0

我試圖訪問一個DepthComponent紋理在我的版本400OpenGL的訪問DepthComponent紋理在GLSL 400

程序做了兩遍渲染GLSL着色器。在第一遍我渲染所有的幾何和顏色到一個Framebuffer,我有一個ColorAttachment和DepthAttachment。該DepthAttachment必然是這樣的:

(注:我使用C#與OpenTK,這是​​強類型的,在我的代碼示例)

GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, depthTexture.ID, 0); 

深度紋理有一個內部的像素格式DepthComponent32f,像素格式爲DepthComponentFloat作爲像素類型。所有其他屬性都有默認值。

第二遍渲染幀緩衝區彩色圖像投影到使用以下着色器中的屏幕:

#version 400 
uniform sampler2D finalImage; 
in vec2 texCoords; 
out vec4 fragColor; 
void main(){ 
    fragColor = vec4(texture2D(finalImage, texCoords.xy).rgb, 1.0); 
} 

但現在我想要閱讀的深度紋理(DepthComponent)代替顏色紋理(RGBA)。

我嘗試了很多東西,像禁用TextureCompareMode,使用shadow2DSampler與shadow2DProj(sampler, vec4(texCoords.xy, 0.0, 1.0))或只是textureProj(sampler, vec3(texCoords.xy, 0.0))。但它只返回1或0,取決於我使用的配置。

要確保我的深度紋理是好的,我讀過的像素回float數組是這樣的:

GL.ReadPixels(0, 0, depthTexture.Width, depthTexture.Height, PixelFormat.DepthComponent, PixelType.Float, float_array); 

一切似乎是正確的,它顯示了我1.0空白和值在可見物體的0.99和1.0之間。

編輯 下面是一個代碼示例我的過程看起來像:

初始化代碼

depthTexture= new GLEXTexture2D(width, height); 
     depthTexture.TextureCompareMode = TextureCompareMode.None; 
     depthTexture.CreateMutable(PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); 
***CreateMutable Function*** 
ReserveTextureID(); 
GLEX.glBeginTexture2D(ID); 
GL.TexImage2D(TextureTarget.Texture2D, 0, pInternalFormat, width, height, 0, pFormat, pType, IntPtr.Zero); 
ApplyOptions(); 
MarkReserved(true); 
GLEX.glEndTexture2D(); 

(上述幀緩衝器附件)

渲染過程1

GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawBuffer.ID); 
     GL.Viewport(0, 0, depthTexture.Width, depthTexture.Height); 
     GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); 
     GL.Enable(EnableCap.DepthTest); 
     GL.ClearColor(Color.Gray); 
     GL.UseProgram(geometryPassShader.ID); 
     geometry_shaderUniformMVPM.SetValueMat4(false, geometryImageMVMatrix * geometryImageProjMatrix); 
     testRectangle.Render(PrimitiveType.QuadStrip); 
     GL.UseProgram(0); 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 

渲染過程2

GL.Viewport(0, 0, depthTexture.Width, depthTexture.Height); 
     GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); 
     GL.ClearColor(Color.White); 
     GL.UseProgram(finalImageShader.ID); 
     GL.ActiveTexture(TextureUnit.Texture0); 

     depthTexture.Bind(); 
     final_shaderUniformMVPM.SetValueMat4(false, finalImageMatrix); 
     screenQuad.Render(PrimitiveType.Quads); 
     GL.UseProgram(0); 
     GL.BindTexture(TextureTarget.Texture2D, 0); 
+1

與從顏色紋理讀取相比,從深度紋理讀取時沒有什麼特別之處。請提供一個最低限度的不工作示例,因爲不可能告訴您的紋理如何綁定等。 – BDL

+0

@BDL添加了我的過程的代碼示例。不包括幾何着色器,因爲它只是使用ReadPixels正確讀取基本着色器和深度值。 – bitQUAKE

+1

無關,但如果您在清除屏幕後設置了清除顏色*,則不會產生任何影響。 – BDL

回答

0

幾個小時後,我發現瞭解決方案。 問題是MinFilter。像Khronos組織上glTexParameter說:

GL_TEXTURE_MIN_FILTER初始值爲GL_NEAREST_MIPMAP_LINEAR

我改變了我的MinFilter深度紋理來GL_NEAREST(其中GL_LINEAR也是合法的),現在在GLSL着色器的深度值是正確的(當然線性化後)。

附加信息: MagFilter有一些擴展,如LINEAR_DETAIL_ALPHA_SGIS。我嘗試了其中的一些,深度值的正確性沒有受到影響。

+0

請評論我的答案,如果有什麼問題。如果一切正常,我會將其標記爲答案。 – bitQUAKE