2014-11-15 216 views
1

我正在將後期處理效果集成到我的3D引擎中。我使用FrameBuffer Object與WebGL來捕獲深度數據。將顏色數據捕獲到FrameBuffer中沒有問題。但是,即使啓用Chrome/Firefox的Depth Extension,我也無法獲得任何深度數據WebGL FrameBuffer - 渲染深度紋理

var DepthEXT = webGLContext.getExtension("WEBKIT_WEBGL_depth_texture") || 
       webGLContext.getExtension("MOZ_WEBGL_depth_texture"); 

我已經嘗試了很多不同的設置,看看它是否是配置問題,但無論我嘗試什麼,我只是看到一個白色的紋理。帖子末尾的截圖顯示顏色附件呈現爲紋理,深度附件呈現爲紋理。我的FrameBuffer初始化有問題,還是應該在其他地方尋找解決此問題的方法?

下面是我對初始化幀緩衝區對象代碼:

// 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); 

這裏就是我渲染當前場景到幀緩衝區的代碼。

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); 
} 

enter image description here

+0

什麼是z軸範圍,如果你有一個近平面的'1.0'和一個遠平面的'1000.0',那麼你就不能在8bit的深度上輸出差異。因此,您的深度緩衝區可能是正確的,但是您的輸出無法將其可視化。你爲什麼要將深度清除到'1.0',你使用了什麼'depthFunc'? –

+0

我的近平面是1.0,遠遠是1000.0。我的depthFunc是depthFunc(LEQUAL)。我調整了近1.0到遠至100.0,我仍然看到一個白色的紋理。 –

+0

對於在深度緩衝區中也有白屏的人:https://stackoverflow.com/a/44357374/3012928 –

回答

3

您不必在設置它的一端連接到您的FBO的深度紋理。您設定的紋理在某些點上深度附件:

// 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); 

只能有一個目標連接到每個FBO連接點。因此,第二次調用將創建一個新的深度附件,替換您在第一次調用中設置的深度附件。所以最後,m_depthComponentTexture不再附加到FBO上了。

如果你想使用深度紋理,我不明白你爲什麼要創建一個深度渲染緩衝區。你應該只需要其中的一個。如果您稍後不需要採樣,通常會使用深度渲染緩衝區。如果你想從結果中抽樣,你需要一個紋理,而不再需要渲染緩衝。