WebGL呈现缓冲区

时间:2019-05-25 09:42:55

标签: webgl

阅读this文章

  

WebGL永远不会是单缓冲的,这意味着您当前渲染的图像永远不会是Canvas元素中当前显示的图像。这样可以确保半渲染的帧永远不会出现在浏览器的窗口中。渲染的图像称为WebGL帧缓冲区或后缓冲区。 WebGL还允许其他屏幕外的帧缓冲区这一事实使谈论帧缓冲区变得更加复杂,但是在本文中我们将忽略它。当前显示的图像称为前缓冲区。当然,后缓冲区的内容有时会复制到前缓冲区中-否则WebGL绘图将不会对用户可见!

我们当前渲染的图像永远不会在画布上显示,那怎么可能?

然后还说,正在渲染的图像称为webGL帧缓冲区或后缓冲区,正在显示的图像称为前缓冲区。有什么不同。有人可以给这篇文章加些亮吗?

1 个答案:

答案 0 :(得分:0)

这很简单。当您制作WebGL画布时,它具有2个缓冲区,即绘图缓冲区(也称为后缓冲区)和显示缓冲区(也称为前缓冲区)。

绘制到绘图缓冲区。

如果您在画布上绘制一些东西,这意味着将gl.cleargl.draw???设置为渲染到画布上时,浏览器会将画布标记为“需要合成”。当前事件结束后,浏览器下次组合页面(将所有元素绘制在一起)时,会将绘图缓冲区复制到显示缓冲区,或者将绘图缓冲区和显示缓冲区交换。

它的作用取决于浏览器和许多其他因素。如果设置preserveDrawingBuffer: true,它将始终将drawubuffer复制到显示缓冲区。如果preserveDrawingBuffer为假(默认设置),则交换或复制取决于浏览器和其他因素,但是无论preserveDrawingBuffer为假,WebGL都会在交换或复制后清除绘图缓冲区,以便您无法分辨出差异,因此无论选择哪种结果都是相同的。

它有2个缓冲区,因为浏览器希望能够并行运行事物。通过这种设计,它可以在需要或需要时随时使用显示缓冲区绘制页面,因为其中包含您上次渲染的结果。没有它,如果您只有绘图缓冲区并再次开始绘图,并且浏览器并行地将所有元素合成在一起,则当它终于要使用时,可能会从绘图缓冲区中获得一半的绘制图像。

请注意,实际上有2个缓冲区是您可以忽略的事实。从WebGL编程的角度来看,实际上只有两种结果

  1. 如果preserveDrawingBuffer为false(默认值),则将清除图形缓冲区,然后浏览器将合成页面。这样做的效果是,您每次更新时都需要绘制所有内容。您不能在每个框架上画一点点。如果要查看3个圆,则需要在同一框架中全部绘制3个圆。这对于大约99%的游戏和大约99%的WebGL应用程序是正常的。在OpenGL,DirectX,Metal,Vulcan等中都是相同的。用这些系统编写的游戏也会在每一帧绘制所有内容。

  2. ,如果您要使用canvas.toDataURLcanvas.toBlobgl.readPixels或任何其他方式从WebGL画布获取数据,除非您在同一事件中进行读取那么当您尝试阅读时可能会很清楚。

    换句话说,如果您这样做

    function render() {
       // draw stuff with WebGL
    }
    
    function renderLoop() {
      render();
      requestAnimationFrame(renderLoop);
    }
    
    someButton.addEventListener('click', () => {
      // take screenshot
      const screenshotDataURL = webglCanvas.toDataURL();
    });
    

    由于用户单击someButton时WebGL可能已清除绘图缓冲区,因此屏幕截图可能会失败。

    解决方案是设置preserveDrawingBuffer: true或确保在同一事件中渲染

    someButton.addEventListener('click', () => {
    
      // !!! render in the click event
      render();                 
    
      // take screenshot
      const screenshotDataURL = webglCanvas.toDataURL();
    });
    

类似地,如果要绘制多个框架(例如绘制程序),那么最简单的解决方案是在创建WebGL上下文时设置preserveDrawingBuffer: true

为了增加混乱,您提到了renderbuffers和framebuffers。这些是WebGL中的特定内容。

renderbuffer就像一个纹理,除了它不同于纹理,它不能用作着色器的输入。只能用作输出。

帧缓冲区是纹理和渲染缓冲区的集合。如果要渲染到纹理,则将一个或多个纹理和渲染缓冲区附加到帧缓冲区。然后,您告诉WebGL您要渲染到帧缓冲区而不是画布。完成后,您可以使用结果渲染到画布上。

有关示例,请参见https://webglfundamentals.org/webgl/lessons/webgl-render-to-texture.html

相关问题