【问题标题】:WEBGL-FBO: Why is the DEPTH_COMPONENT texture blank after rendercallWEBGL-FBO:为什么渲染调用后 DEPTH_COMPONENT 纹理为空白
【发布时间】:2020-03-04 00:47:09
【问题描述】:

致读者: “gman 的解决方案适用于该问题,但我自己的问题是代码的不同部分”。

我只是想将我的场景渲染到带有 DepthComponent_textuture 的帧缓冲区。并且想将此纹理渲染到屏幕上,以便我在我的屏幕上看到 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();
    }
}

【问题讨论】:

  • 是的,我确实清除了缓冲区。现在我在绑定 Framebuffer 时也再次启用了 DepthTesting(我认为我真的不需要这样做,因为我在 gl 初始化时已经这样做了)。
  • 是的,我在 renderScene() 中做了,我总是在开始渲染之前清除当前绑定的帧缓冲区
  • 您是否在检查 JavaScript 控制台是否有错误?您是否检查并启用了深度纹理扩展?深度纹理不是 WebGL1 的默认功能。 gl.DEPTH_COMPONENT16 不是有效的纹理格式。 gl.DEPTH_COMPONENT 仅当您检查并启用了 WEBGL_depth_texture 扩展
  • 我的控制台很干净,我第一次尝试使用 texImage2d 对 depthTexture 进行纹理处理,但控制台中的纹理格式无效。如何启用 WEBGL_depth_texture
  • 你的意思是let x = gl.getExtension('WEBGL_depth_texture');我应该在哪里添加这个

标签: javascript framebuffer webgl2


【解决方案1】:

这是在 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>

【讨论】:

  • 非常感谢我让它工作了,我有一个绑定到 Framebuffer 的 DepthRenderbuffer,它覆盖了 DepthAttachment(我忘记了 switch 语句中的中断)。我还编辑了 ScreenShaders fragmentShader,以便将深度值提高到 100.0 的幂,否则我看不到任何东西,因为那时一切都是白色的。谢谢你帮了很多忙。
猜你喜欢
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
相关资源
最近更新 更多