繁体   English   中英

WebGL:带有深度模板纹理附件的帧缓冲区上的颜色未清除

[英]WebGL: Color not cleared on framebuffer with depth stencil texture attachment

我尝试在启用模板的情况下绘制对象,并且一切正常。 下面是我期望的工作结果的动画帧(从左到右)的图片。 预期结果

当我使用帧缓冲区时会出现问题。 据我了解,WebGL 1.0 不支持将模板与深度分开,无论是来自渲染缓冲区还是纹理。 可以通过WEBGL_depth_texture扩展将模板和深度附加在一起来WEBGL_depth_texture 我正在使用该扩展并使用帧缓冲区,绘制对象,但结果似乎不清楚颜色。 下面是结果的动画帧的图片。

在此处输入图片说明

有人可以解释发生了什么吗?

请浏览下面的完整代码。

 (function() { var gl; var dtExt; var gProgram; var gRectShader; var gVertexAttribLocation; var gColorAttribLocation; var gRectVertexAttribLocation; var gRectTexcoordAttribLocation; var gModelViewMatrixUniform; var gTriangleVertexBuffer; var gTriangleColorBuffer; var gQuadVertexBuffer; var gQuadColorBuffer; var gQuadTexcoordBuffer; var gFramebuffer; var gColorTexture; var gDepthStencilTexture; var rotationMatrix = mat4.create(); function initGL() { var glcanvas = document.getElementById("glcanvas"); gl = glcanvas.getContext("webgl", {stencil:true}); dtExt = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('WEBKIT_WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture'); } function initFramebuffers() { gFramebuffer = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, gFramebuffer); gl.bindTexture(gl.TEXTURE_2D, gColorTexture); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, gColorTexture, 0); gl.bindTexture(gl.TEXTURE_2D, gDepthStencilTexture); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, gDepthStencilTexture, 0); gl.bindTexture(gl.TEXTURE_2D, null); gl.bindFramebuffer(gl.FRAMEBUFFER, null); } function createTexture() { var texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); 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.bindTexture(gl.TEXTURE_2D, null); return texture; } function initTextures() { gColorTexture = createTexture(); gl.bindTexture(gl.TEXTURE_2D, gColorTexture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gDepthStencilTexture = createTexture(); gl.bindTexture(gl.TEXTURE_2D, gDepthStencilTexture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_STENCIL, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.DEPTH_STENCIL, dtExt.UNSIGNED_INT_24_8_WEBGL, null); gl.bindTexture(gl.TEXTURE_2D, null); } function createAndCompileShader(type, source) { var shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { throw new Error(gl.getShaderInfoLog(shader)); } return shader; } function createAndLinkProgram(glVertexShader, glFragmentShader) { var glProgram = gl.createProgram(); gl.attachShader(glProgram, glVertexShader); gl.attachShader(glProgram, glFragmentShader); gl.linkProgram(glProgram); if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) { throw new Error("Could not initialise shaders"); } return glProgram; } function initShaderPrograms() { var gVertexShader = createAndCompileShader(gl.VERTEX_SHADER, [ "attribute vec3 a_vertex;", "attribute vec4 a_color;", "uniform mat4 u_modelViewMatrix;", "varying vec4 v_color;", "void main(void) {", "v_color = a_color;", "gl_Position = u_modelViewMatrix * vec4(a_vertex, 1.0);", "}" ].join("\\n")); var gFragmentShader = createAndCompileShader(gl.FRAGMENT_SHADER, [ "precision mediump float;", "varying vec4 v_color;", "void main(void) {", "gl_FragColor = v_color;", "}" ].join("\\n")); gProgram = createAndLinkProgram(gVertexShader, gFragmentShader); var gVertexShader = createAndCompileShader(gl.VERTEX_SHADER, [ "attribute vec3 a_vertex;", "attribute vec2 a_texcoord;", "varying vec2 v_texcoord;", "void main(void) {", "v_texcoord = a_texcoord;", "gl_Position = vec4(a_vertex, 1.0);", "}" ].join("\\n")); var gFragmentShader = createAndCompileShader(gl.FRAGMENT_SHADER, [ "precision mediump float;", "uniform sampler2D u_sampler0;", "varying vec2 v_texcoord;", "void main(void) {", "gl_FragColor = texture2D(u_sampler0, v_texcoord);", "}" ].join("\\n")); gRectShader = createAndLinkProgram(gVertexShader, gFragmentShader); } function initAttribAndUniformLocations() { gVertexAttribLocation = gl.getAttribLocation(gProgram, "a_vertex"); gColorAttribLocation = gl.getAttribLocation(gProgram, "a_color"); gModelViewMatrixUniform = gl.getUniformLocation(gProgram, 'u_modelViewMatrix'); gRectVertexAttribLocation = gl.getAttribLocation(gRectShader, "a_vertex"); gRectTexcoordAttribLocation = gl.getAttribLocation(gRectShader, "a_texcoord"); } function initBuffers() { gTriangleVertexBuffer = gl.createBuffer(); gTriangleColorBuffer = gl.createBuffer(); gQuadVertexBuffer = gl.createBuffer(); gQuadColorBuffer = gl.createBuffer(); gQuadTexcoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, gTriangleVertexBuffer); var vertices = new Float32Array([ 0.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, ]); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, gTriangleColorBuffer); var colors = new Float32Array([ 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0 ]); gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, gQuadVertexBuffer); var vertices = new Float32Array([ -1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 1.0, -1.0, 0.0 ]); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, gQuadColorBuffer); var colors = new Float32Array([ 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0 ]); gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, gQuadTexcoordBuffer); var texcoords = new Float32Array([ 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 ]); gl.bufferData(gl.ARRAY_BUFFER, texcoords, gl.STATIC_DRAW); } function drawQuads() { gl.bindBuffer(gl.ARRAY_BUFFER, gQuadVertexBuffer); gl.vertexAttribPointer(gVertexAttribLocation, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, gQuadColorBuffer); gl.vertexAttribPointer(gColorAttribLocation, 4, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); } function drawRectQuads() { gl.bindBuffer(gl.ARRAY_BUFFER, gQuadVertexBuffer); gl.vertexAttribPointer(gRectVertexAttribLocation, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, gQuadTexcoordBuffer); gl.vertexAttribPointer(gRectTexcoordAttribLocation, 2, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); } function drawTriagles() { gl.bindBuffer(gl.ARRAY_BUFFER, gTriangleVertexBuffer); gl.vertexAttribPointer(gVertexAttribLocation, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, gTriangleColorBuffer); gl.vertexAttribPointer(gColorAttribLocation, 4, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.TRIANGLES, 0, 6); } function renderScene() { var mvMatrix = mat4.create(); gl.clearColor(0.5, 0.5, 0.5, 1.0); gl.bindFramebuffer(gl.FRAMEBUFFER, gFramebuffer); gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.enable(gl.STENCIL_TEST); gl.enable(gl.DEPTH_TEST); gl.enable(gl.CULL_FACE); gl.clear(gl.STENCIL_BUFFER_BIT); gl.useProgram(gProgram); gl.enableVertexAttribArray(gVertexAttribLocation); gl.enableVertexAttribArray(gColorAttribLocation); gl.disable(gl.DEPTH_TEST); gl.colorMask(false, false, false, false); gl.stencilFunc(gl.ALWAYS, 0, 0xff); gl.stencilMask(0xff); gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.INCR); gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.DECR); mat4.identity(mvMatrix); mat4.scale(mvMatrix, mvMatrix, [0.5, 0.5, 0.5]); mat4.multiply(mvMatrix, mvMatrix, rotationMatrix); gl.uniformMatrix4fv(gModelViewMatrixUniform, false, mvMatrix); gl.cullFace(gl.FRONT); drawTriagles(); gl.cullFace(gl.BACK); drawTriagles(); gl.stencilMask(0x00); gl.stencilFunc(gl.NOTEQUAL, 0, 0xff); gl.enable(gl.DEPTH_TEST); gl.colorMask(true, true, true, true); mat4.identity(mvMatrix); mat4.scale(mvMatrix, mvMatrix, [0.75, 0.75, 0.75]); gl.uniformMatrix4fv(gModelViewMatrixUniform, false, mvMatrix); drawQuads(); gl.disableVertexAttribArray(gVertexAttribLocation); gl.disableVertexAttribArray(gColorAttribLocation); gl.flush(); gl.disable(gl.STENCIL_TEST); gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); gl.enable(gl.DEPTH_TEST); gl.bindTexture(gl.TEXTURE_2D, gColorTexture); gl.useProgram(gRectShader); gl.enableVertexAttribArray(gRectVertexAttribLocation); gl.enableVertexAttribArray(gRectTexcoordAttribLocation); drawRectQuads(); gl.disableVertexAttribArray(gRectVertexAttribLocation); gl.disableVertexAttribArray(gRectTexcoordAttribLocation); gl.flush(); } function step(timestamp) { renderScene(); mat4.rotate(rotationMatrix, rotationMatrix, Math.PI / 360, [0, 0, 1]) window.requestAnimationFrame(step); } initGL(); initShaderPrograms(); initAttribAndUniformLocations(); initTextures(); initFramebuffers(); initBuffers(); window.requestAnimationFrame(step); }());
 <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script> <canvas id="glcanvas" width="480" height="360"> WebGL not supported! </canvas>

您需要在清除模板缓冲区之前设置模板蒙版

gl.stencilMask(0xff);

此外,您不需要WEBGL_depth_texture来为帧缓冲区制作深度+模板附件。 您可以使用 DEPTH_STENCIL 渲染缓冲区

const rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb);

此外, 多行模板文字可能会为您节省大量时间。

gl.flush在代码中也没有意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM