I am in the process of integrating post processing effects into my 3D engine. I have hit a roadblock with capturing depth data using a FrameBuffer Object with WebGL. There has been no issue capturing color data into the FrameBuffer. However, I am not able to get any Depth data even with the Depth Extension enabled for Chrome/Firefox.
var DepthEXT = webGLContext.getExtension( "WEBKIT_WEBGL_depth_texture" ) ||
webGLContext.getExtension( "MOZ_WEBGL_depth_texture" );
I have tried many different settings to see if it was a configuration issue, but no matter what I try I just see a white texture. The screenshot at the end of the post shows the color attachment rendered as a texture and the depth attachment rendered as a texture. Is there a problem with my initialization of the FrameBuffer or should I be looking elsewhere to solve this issue?
Below is my code for initializing the FrameBuffer Object:
// Frame Buffer
this.m_frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, this.m_frameBuffer );
// Render Buffer
this.m_renderBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer( gl.RENDERBUFFER, this.m_renderBuffer );
gl.renderbufferStorage(
gl.RENDERBUFFER,
gl.DEPTH_COMPONENT16,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height );
// Diffuse Component
this.m_diffuseComponentTexture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, this.m_diffuseComponentTexture );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MAG_FILTER,
gl.LINEAR );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MIN_FILTER,
gl.LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height,
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
null );
// Depth
this.m_depthComponentTexture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, this.m_depthComponentTexture );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MAG_FILTER,
gl.NEAREST );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MIN_FILTER,
gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.DEPTH_COMPONENT,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height,
0,
gl.DEPTH_COMPONENT,
gl.UNSIGNED_SHORT,
null );
// FrameBuffer
// Diffuse
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
this.m_diffuseComponentTexture,
0 );
// Depth
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.TEXTURE_2D,
this.m_depthComponentTexture,
0 );
// RenderBuffer
gl.framebufferRenderbuffer(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER,
this.m_renderBuffer );
// Unbind buffers and textures
gl.bindTexture( gl.TEXTURE_2D, null );
gl.bindRenderbuffer( gl.RENDERBUFFER, null );
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
Here is the code where I render the current scene to the FrameBuffer.
CBRenderer.prototype.renderSceneToGBuffer = function( sceneToRender, GBufferTarget, deltaSeconds )
{
CBMatrixStack.clearMatrixStackAndPushIdentityMatrix();
this.applyProjectionMatrix();
GBufferTarget.bindGBufferFrameBuffer();
this.renderer.enable( this.renderer.DEPTH_TEST );
this.renderer.depthMask( true );
this.renderer.clearDepth( 1.0 );
this.renderer.clearColor( 0.1, 0.1, 0.1, 0.0 );
this.renderer.clear( this.renderer.COLOR_BUFFER_BIT | this.renderer.DEPTH_BUFFER_BIT );
sceneToRender.render( deltaSeconds );
this.renderer.flush();
GBufferTarget.m_dirty = false;
GBufferTarget.unbindGBufferFrameBuffer();
this.renderer.clearColor( 0.0, 0.0, 0.0, 0.0 );
this.renderer.clear( this.renderer.COLOR_BUFFER_BIT | this.renderer.DEPTH_BUFFER_BIT );
this.renderer.bindTexture( this.renderer.TEXTURE_2D, null );
}
I am in the process of integrating post processing effects into my 3D engine. I have hit a roadblock with capturing depth data using a FrameBuffer Object with WebGL. There has been no issue capturing color data into the FrameBuffer. However, I am not able to get any Depth data even with the Depth Extension enabled for Chrome/Firefox.
var DepthEXT = webGLContext.getExtension( "WEBKIT_WEBGL_depth_texture" ) ||
webGLContext.getExtension( "MOZ_WEBGL_depth_texture" );
I have tried many different settings to see if it was a configuration issue, but no matter what I try I just see a white texture. The screenshot at the end of the post shows the color attachment rendered as a texture and the depth attachment rendered as a texture. Is there a problem with my initialization of the FrameBuffer or should I be looking elsewhere to solve this issue?
Below is my code for initializing the FrameBuffer Object:
// Frame Buffer
this.m_frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer( gl.FRAMEBUFFER, this.m_frameBuffer );
// Render Buffer
this.m_renderBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer( gl.RENDERBUFFER, this.m_renderBuffer );
gl.renderbufferStorage(
gl.RENDERBUFFER,
gl.DEPTH_COMPONENT16,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height );
// Diffuse Component
this.m_diffuseComponentTexture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, this.m_diffuseComponentTexture );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MAG_FILTER,
gl.LINEAR );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MIN_FILTER,
gl.LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height,
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
null );
// Depth
this.m_depthComponentTexture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, this.m_depthComponentTexture );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MAG_FILTER,
gl.NEAREST );
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MIN_FILTER,
gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.DEPTH_COMPONENT,
sharedRenderer.canvasDOMElement.width,
sharedRenderer.canvasDOMElement.height,
0,
gl.DEPTH_COMPONENT,
gl.UNSIGNED_SHORT,
null );
// FrameBuffer
// Diffuse
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
this.m_diffuseComponentTexture,
0 );
// Depth
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.TEXTURE_2D,
this.m_depthComponentTexture,
0 );
// RenderBuffer
gl.framebufferRenderbuffer(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER,
this.m_renderBuffer );
// Unbind buffers and textures
gl.bindTexture( gl.TEXTURE_2D, null );
gl.bindRenderbuffer( gl.RENDERBUFFER, null );
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
Here is the code where I render the current scene to the FrameBuffer.
CBRenderer.prototype.renderSceneToGBuffer = function( sceneToRender, GBufferTarget, deltaSeconds )
{
CBMatrixStack.clearMatrixStackAndPushIdentityMatrix();
this.applyProjectionMatrix();
GBufferTarget.bindGBufferFrameBuffer();
this.renderer.enable( this.renderer.DEPTH_TEST );
this.renderer.depthMask( true );
this.renderer.clearDepth( 1.0 );
this.renderer.clearColor( 0.1, 0.1, 0.1, 0.0 );
this.renderer.clear( this.renderer.COLOR_BUFFER_BIT | this.renderer.DEPTH_BUFFER_BIT );
sceneToRender.render( deltaSeconds );
this.renderer.flush();
GBufferTarget.m_dirty = false;
GBufferTarget.unbindGBufferFrameBuffer();
this.renderer.clearColor( 0.0, 0.0, 0.0, 0.0 );
this.renderer.clear( this.renderer.COLOR_BUFFER_BIT | this.renderer.DEPTH_BUFFER_BIT );
this.renderer.bindTexture( this.renderer.TEXTURE_2D, null );
}
Share
Improve this question
asked Nov 15, 2014 at 22:50
Paul RentonPaul Renton
2,6906 gold badges26 silver badges40 bronze badges
3
-
Whats your z-range, if you have a nearplane of
1.0
and a far plane of1000.0
you're not able to output the difference in depth in just 8bit . So your depth buffer may be correct but your output is not able to visualize it. Why are you clearing your depth to1.0
, whatdepthFunc
do you use? – LJᛃ Commented Nov 16, 2014 at 0:19 - My near plane is 1.0 and far is 1000.0. My depthFunc is depthFunc( LEQUAL ). I adjusted the near to 1.0 and far to 100.0 and am still just seeing a white texture. – Paul Renton Commented Nov 16, 2014 at 0:31
- For people who have also white screen in the depth buffer: stackoverflow./a/44357374/3012928 – Ice-Blaze Commented Jun 4, 2017 at 18:27
1 Answer
Reset to default 5You don't have the depth texture attached to your FBO at the end of setting it up. You do set the texture as the depth attachment at some point:
// Depth
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.TEXTURE_2D,
this.m_depthComponentTexture,
0 );
But immediately following that, you set a renderbuffer as the depth attachment instead:
// RenderBuffer
gl.framebufferRenderbuffer(
gl.FRAMEBUFFER,
gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER,
this.m_renderBuffer );
You can have only one target attached to each FBO attachment point. So the second call sets a new depth attachment, replacing the one you just set in the first call. So at the end of this, m_depthComponentTexture
is not attached to the FBO anymore.
If you want to use a depth texture, I don't see why you would want to create a depth renderbuffer as well. You should only need one of the two. You would normally use a renderbuffer for the depth if you don't need it for sampling later. If you want to sample from the result, you need a texture instead, and there's no need for a renderbuffer anymore.