在屏幕上的深度纹理

时间:2015-03-24 20:30:07

标签: opengl-es webgl depth-buffer

我试图在屏幕上获得深度纹理,我总是得到一个空白屏幕。我不确定我做错了什么。我看过一些关于将FBO绘制成“四边形”的帖子,但我不清楚如何这样做。 这是我的代码(我使用深度纹理扩展,如此处所示http://blog.tojicode.com/2012/07/using-webgldepthtexture.html):

function initGLTextureFrameBuffer()
{

var depthTextureExt = gl.getExtension("WEBKIT_WEBGL_depth_texture");
if (!depthTextureExt) return;   

rttFramebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer);
rttFramebuffer.width = 512;
rttFramebuffer.height = 512;
colorTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
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, rttFramebuffer.width,rttFramebuffer.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

depthTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, depthTexture);
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, rttFramebuffer.width, rttFramebuffer.height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);


gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture,0);

gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);

}

这是我的渲染功能:

function drawOverlayTriangles()
{

gl.enableVertexAttribArray(shaderProgram.aVertexPosition);
gl.enableVertexAttribArray(shaderProgram.aTextureCoord);

gl.vertexAttrib1f(shaderProgram.aHasTexture, 1.0);
gl.vertexAttrib1f(shaderProgram.aisdepth, 1.0);
gl.bindBuffer(gl.ARRAY_BUFFER, imageTextureCoord);
gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0);

//Matrix upload
gl.uniformMatrix4fv(shaderProgram.uMVMatrix, false, pMVMatrix);
gl.uniformMatrix4fv(shaderProgram.uPMatrix, false, perspM);

gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer); 
gl.bindTexture(gl.TEXTURE_2D, depthTexture);
gl.uniform1i(shaderProgram.dTexture, 0);    

gl.clearColor(0,0,0,1);
gl.clear(gl.DEPTH_BUFFER_BIT |  gl.COLOR_BUFFER_BIT);   


for (var i = 0; i < overlay.numElements; i++) {
    // Upload overlay vertices                      
    gl.bindBuffer(gl.ARRAY_BUFFER, overlayVertices[i]);
    gl.vertexAttribPointer(shaderProgram.aVertexPosition, 3, gl.FLOAT, false, 0, 0);

    // Upload overlay colors
    gl.bindBuffer(gl.ARRAY_BUFFER, overlayTriangleColors[i]);       
    gl.vertexAttribPointer(shaderProgram.aVertexColor, 4, gl.FLOAT, false, 0, 0);

    // Draw overlay
    gl.drawArrays(gl.TRIANGLES, 0, overlay.elementNumVertices[i]);
}

gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);

gl.disableVertexAttribArray(shaderProgram.aVertexPosition);
gl.disableVertexAttribArray(shaderProgram.aVertexColor);
gl.vertexAttrib1f(shaderProgram.aisdepth, 0.0);
}

这是我的片段着色器代码:

    varying vec4 vColor;
    varying float vHasTexture;
    varying vec2 vTextureCoord;
    varying float visdepth;
    varying vec4 position_1;
    varying float DEPTH;

    uniform sampler2D uTexture;
    uniform float uTextureAlpha;

    uniform sampler2D dTexture;

    void main(void) {
        if (vHasTexture < 0.5 && visdepth < 0.5)
                gl_FragColor = vColor;

        if (vHasTexture > 0.5) 
        {   
            vec4 textureColor = texture2D(uTexture, vec2(vTextureCoord.s, vTextureCoord.t));
                gl_FragColor = vec4(textureColor.rgb, textureColor.a * uTextureAlpha);
        }

        if (visdepth > 0.5)
        {
            float z = texture2D(dTexture, vec2(vTextureCoord.s, vTextureCoord.t)).r;
            float n = 1.0;
            float f = 30.0;
            float c = (2.0 * n) / (f + n - z * (f - n));
            gl_FragColor.rgb = vec3(c);

        }   
    }

我会感激任何帮助,因为我一直试图这样做一个星期没有运气。

1 个答案:

答案 0 :(得分:2)

看起来你正试图在同一个传递中读取和写入深度纹理。你有:

gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture,0);

gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer); 
gl.bindTexture(gl.TEXTURE_2D, depthTexture);

这将为您提供未定义的结果。你需要一个两遍算法。在第一遍中,您将渲染到您创建的帧缓冲区。在第二遍中,您将渲染到默认的帧缓冲区(gl.bindFramebuffer(gl.FRAMEBUFFER,0);),其中深度纹理被绑定以供阅读。

或者,如果您只关心将深度值显示为颜色(而不是使用深度作为另一个渲染过程的输入),则可以替换该行

float z = texture2D(dTexture, vec2(vTextureCoord.s, vTextureCoord.t)).r;

float z = gl_FragCoord.z;

这样你就不会从你正在写的相同深度纹理中读取。内置变量gl_FragCoord是当前片段的窗口坐标。 https://www.opengl.org/sdk/docs/man/html/gl_FragCoord.xhtml

在这种情况下,您只需渲染到默认的帧缓冲区,而不是渲染到您创建的帧缓冲区。