WEBGL-FBO:为什么渲染调用后DEPTH_COMPONENT纹理为空白

问题描述 投票:1回答:1

致读者:“ gman的解决方案适用于该问题,但是我自己的问题在《守则》的不同部分中。”

我只想将我的场景渲染到具有DepthComponent_texuture的帧缓冲区。并希望将此纹理渲染到屏幕上,以便我可以在屏幕上看到DepthComponent。我想进入Shadowmapping,这是一个很好的练习。

我所做的事情:-set read/drawBuffer(s)gl.NONE,因为我没有colorAttachment(甚至可能不重要)。-创建深度纹理时,我尝试了gl.texImage2D,但无法使其正常工作。-当我使用由DepthAttachment填充的ColorAttachment时,我得到了正常结果(颜色Attachment_texture只是具有可见性)[显然,在这里我还添加了DepthRenderbuffer(DEPTH24STENCTIL8)]。

//creating the Framebuffer
id = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER,id);

atex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, atex);
gl.texStorage2D(gl.TEXTURE_2D,1,gl.DEPTH_COMPONENT16,width,height);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_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.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, atex, 0);

gl.drawBuffers([gl.NONE]);
gl.readBuffer(gl.NONE);

gl.bindFramebuffer(gl.FRAMEBUFFER,null);
//----------------
//In the renderLoop

//renders the scene with the pbrShader to the Framebuffer
//The FragmentShader of the PBRShader is empty cause i dont have any 
//ColorAttachments and the Vertex is just transforming the position and
//passing the uvs[...]
render(scene,pbrShader,framebuffer);
//renders a texture to the screen using a very simple vertex shader and
//a Fragment Shader that just takes the texture and mapps it to the Screen
renderScreen(framebuffer.atex);



//Some more Code for clarity:
renderScene(scene,shader,fbo=null){
   if(fbo!=null){
       fbo.activate();
   }
   this.gl.fClear();
   let batches = new Map();
   let modals = scene.getEntitiesByType("modal");
   modals.forEach(modal=>{
        if(batches.has(modal.mesh)){
            batches.get(modal.mesh).push(modal);
        }else{
            batches.set(modal.mesh,[modal]);
        }
    })
    shader.activate().prepareScene(scene);
    batches.forEach((batch,mesh)=>{
        shader.prepareVAO(mesh);
        batch.forEach(modal=>{
             shader.prepareInstance(modal);
             shader.drawVAO(mesh);
        });
        shader.unbindVAO(mesh);
    });
    shader.deactivate();
    if(fbo!=null){
        fbo.deactivate();
    }
}
javascript framebuffer webgl2
1个回答
0
投票

这里是在WebGL2中使用深度纹理的工作示例

const vs = `#version 300 es
layout(location = 0) in vec4 a_position;

out vec2 v_texcoord;

void main() {
  gl_Position = a_position;
  v_texcoord = a_position.xy * 0.5 + 0.5;
}
`;

const fs = `#version 300 es
precision mediump float;
in vec2 v_texcoord;
uniform sampler2D u_sampler;
out vec4 outColor;
void main() {
    vec4 color = texture(u_sampler, v_texcoord);
    outColor = vec4(color.r, 0, 0, 1);
}
`;

function main() {
  var gl = document.querySelector("canvas").getContext('webgl2');
  if (!gl) {
    return alert("no WebGL2");
  }

  var program = twgl.createProgram(gl, [vs, fs]);
  gl.useProgram(program);

  var verts = [
     1,  1,  1, 
    -1,  1,  0, 
    -1, -1, -1,
     1,  1,  1, 
    -1, -1, -1,
     1, -1,  0,
  ];
  var vertBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
  gl.enableVertexAttribArray(0);
  gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);

  // create a depth texture.
  var depthTex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, depthTex);
  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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  const mipLevel = 0;
  const depthTexWidth = 16;
  const depthTexHeight = 16;
  gl.texImage2D(
      gl.TEXTURE_2D, mipLevel, gl.DEPTH_COMPONENT24, 
      depthTexWidth, depthTexHeight, 0,
      gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);

  // Create a framebuffer and attach the textures.
  var fb = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
    gl.TEXTURE_2D, depthTex, 0);

  // use some other texture to render with while we render to the depth texture.
  const tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.texImage2D(
    gl.TEXTURE_2D, 0, gl.RGBA8,
    1, // width
    1, // height
    0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255]));

  // Turn on depth testing so we can write to the depth texture.
  gl.enable(gl.DEPTH_TEST);
  
  // note: we don't need to set u_sampler because uniforms
  // default to 0 so it will use texture unit 0 which
  // is the also the default active texture unit

  // Render to the depth texture
  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
  gl.viewport(0, 0, depthTexWidth, depthTexHeight);
  gl.clear(gl.DEPTH_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLES, 0, 6);

  // Now draw with the texture to the canvas
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  gl.bindTexture(gl.TEXTURE_2D, depthTex);
  gl.drawArrays(gl.TRIANGLES, 0, 6);
}
main();
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>
© www.soinside.com 2019 - 2024. All rights reserved.