我试图在屏幕上获得深度纹理,我总是得到一个空白屏幕。我不确定我做错了什么。我看过一些关于将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);
}
}
我会感激任何帮助,因为我一直试图这样做一个星期没有运气。
答案 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
在这种情况下,您只需渲染到默认的帧缓冲区,而不是渲染到您创建的帧缓冲区。