2011-08-31 144 views
12

對於後期處理着色器,我需要我的幀緩衝區的顏色和深度緩衝區。訪問colorbuffer工作正常,但我在創建depthbuffer時遇到問題。嘗試使用texImage2D的深度紋理時,我總是得到一個錯誤INVALID_ENUM:WebGL - 渲染到fbo紋理的深度不起作用

WebGL error INVALID_ENUM in texImage2D(TEXTURE_2D, 0, DEPTH_COMPONENT16, 1536, 502, 0, DEPTH_COMPONENT, UNSIGNED_BYTE, null) 

使用渲染,而不是紋理的作品,但我想深入紋理,所以我可以將它傳遞給着色器。

幀緩衝器與深度紋理代碼:

Framebuffer.prototype.initBufferStuffTexture = function(width, height){ 
    if(this.width == width && this.height == height){ 
     return; 
    } 

    this.width = width; 
    this.height = height; 

    // remove existing buffers 
    gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
    if(this.texture != null){ 
     gl.deleteTexture(this.texture.glid); 
     this.texture = null; 
    } 
    if(this.renderbuffer != null){ 
     gl.deleteRenderbuffer(this.renderbuffer); 
     this.renderbuffer = null; 
    } 
    if(this.framebuffer != null){ 
     gl.deleteFramebuffer(this.framebuffer); 
     this.framebuffer = null; 
    } 

    // create new buffers 
    this.framebuffer = gl.createFramebuffer(); 
    this.texture = new Texture(); 
    this.texture.glid = gl.createTexture(); 
    this.depth = new Texture(); 
    this.depth.glid = gl.createTexture(); 

    // framebuffer 
    gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); 
    this.framebuffer.width = width; 
    this.framebuffer.height = height; 

    // colorbuffer 
    gl.bindTexture(gl.TEXTURE_2D, this.texture.glid); 
    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.RGBA, this.framebuffer.width, this.framebuffer.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 

    // depthbuffer 
    gl.bindTexture(gl.TEXTURE_2D, this.depth.glid); 
    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_COMPONENT16, this.framebuffer.width, this.framebuffer.height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_BYTE, null); 

    // assemble buffers 
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.glid, 0); 
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, this.depth.glid, 0); 

    this.checkBuffer(); 

    gl.bindTexture(gl.TEXTURE_2D, null); 
    gl.bindRenderbuffer(gl.RENDERBUFFER, null); 
    gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
} 

回答

7

OpenGL ES 2.0規範(針對其指定WebGL)沒有列出GL_DEPTH_COMPONENT(或其任何大小的版本)作爲有效的紋理內部格式,因此它似乎不支持深度紋理,並且WebGL規範不支持狀態不同的任何地方,它也不支持深度紋理。

但也許這個link是有幫助的,其中深度txtures通過將深度值打包到標準rgba紋理中在WebGL中模擬。

+0

謝謝你指出。如果我理解正確,獲取深度信息的唯一方法是添加另一個通道,使用着色器將整個場景渲染爲rgba紋理,該着色器將深度值作爲rgba值輸出。 我想我必須拋開後處理。只渲染一次場景需要很長時間,我無法將它渲染兩次。它由幾百萬分組成。 – Markus

+0

@Markus你也可以使用多個渲染目標(渲染到具有多種顏色附件的FBO中,因此可以從片段着色器編寫多種顏色),但我不知道WebGL支持多遠。 –

+0

關於mrts的帖子說這是不可能的,規範只定義了「COLOR_ATTACHMENT0」。多麼可惜,這也是一個不錯的功能。 – Markus

-3

texImage2D(TEXTURE_2D,0,DEPTH_COMPONENT16,1536,502,0,DEPTH_COMPONENT,UNSIGNED_BYTE,NULL)

OpenGL ES的一向像素傳輸參數比桌面GL更具限制性。因此,即使實際上沒有上傳任何數據,您也必須確保像素傳輸參數符合您的內部格式。因此請嘗試UNSIGNED_SHORT而不是UNSIGNED_BYTE。

+0

也不管用。 SHORT,BYTE,UNSIGNED_INT,INT和FLOAT都不帶DEPTH_COMPONENT或DEPTH_COMPONENT16 – Markus