WebGL显示帧缓冲区?

Posted

技术标签:

【中文标题】WebGL显示帧缓冲区?【英文标题】:WebGL display framebuffer? 【发布时间】:2013-04-29 20:19:06 【问题描述】:

我使用了 WEBKIT_WEBGL_depth_texture 扩展。 并初始化下面的缓冲区。 但是我怎么能画出这个帧缓冲区呢?我现在完全被困住了。 -.-

function InitDepthtextures ()


var size = 256;

// Create a color texture
var 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, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

// Create the depth texture
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, size, size, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);

framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);


//set to default
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);

【问题讨论】:

【参考方案1】:

您不绘制帧缓冲区。你绘制纹理。因此,首先将纹理附加到帧缓冲区。现在,使用该帧缓冲区绑定,绘制一些东西,结果被绘制到帧缓冲区的附件中。接下来取消绑定帧缓冲区并使用附加到帧缓冲区的纹理绘制一些东西以查看它们的内容。

例子:

const gl = document.querySelector('#c').getContext('webgl');

const vshader = `
    attribute vec4 a_position;
    varying vec2 v_texcoord;

    void main() 
      gl_Position = a_position;
      v_texcoord = a_position.xy * 0.5 + 0.5;
        
`;
const fshader = `
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_sampler;
void main() 
    gl_FragColor = texture2D(u_sampler, v_texcoord);

`;

// compiles shaders, links program
const program = twgl.createProgram(gl, [vshader, fshader]);
gl.useProgram(program);

const positionLocation = gl.getAttribLocation(program, "a_position");

// a single triangle from top right to bottom left to bottom right
const verts = [
      1,  1,
     -1,  1,
     -1, -1,
];   
const vertBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);

  const numElements = 2;
  const type = gl.FLOAT;
  const normalize = false;
  const stride = 0;
  const offset = 0;
  gl.vertexAttribPointer(
      positionLocation, numElements, type, normalize, stride, offset);
  gl.enableVertexAttribArray(positionLocation);


// create an empty texture
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);

  const level = 0;
  const internalFormat = gl.RGBA;
  const width = 1;
  const height = 1;
  const border = 0;
  const format = gl.RGBA;
  const type = gl.UNSIGNED_BYTE;
  const data = null;
  gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, width, height, border,
                format, type, data);


// Create a framebuffer and attach the texture.
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);

  const level = 0
  gl.framebufferTexture2D(
      gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, level);


// Render to the texture (using clear because it's simple)
gl.clearColor(0, 1, 0, 1); // green;
gl.clear(gl.COLOR_BUFFER_BIT);

// Now draw with the texture to the canvas
// NOTE: We clear the canvas to red so we'll know
// so anywhere that shows up green is coming from the canvas texture
// from above.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.clearColor(1, 0, 0, 1); // red
gl.clear(gl.COLOR_BUFFER_BIT);

  const offset = 0;
  const count = 3;
  gl.drawArrays(gl.TRIANGLES, offset, count);
canvas  border: 1px solid black; 
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas id="c"  ></canvas>

您可以阅读有关此主题的更多信息here

【讨论】:

jsfiddle 不再有效。此答案还要求您使用导入一些外部库。看看如何仅使用 webgl 来做到这一点会很有趣。 已更新。它仍然使用外部库来编译着色器。你可以阅读为什么here。您还可以更详细地阅读此主题here

以上是关于WebGL显示帧缓冲区?的主要内容,如果未能解决你的问题,请参考以下文章

webGL - 如何在帧缓冲区旁边设置模板缓冲区并使用它?

WebGL 帧缓冲区 ClearColor 仅影响 (0,0) 像素

WebGL:显示深度纹理

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

如何在 webgl 中使用帧缓冲目标?

Opengl 和 Webgl:从附加到当前帧缓冲区的纹理中采样