Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WebGL渲染缓冲区_Webgl - Fatal编程技术网

WebGL渲染缓冲区

WebGL渲染缓冲区,webgl,Webgl,阅读文章 WebGL从来都不是单缓冲的,这意味着当前渲染的图像永远不是当前显示在画布元素中的图像。这可确保半渲染帧永远不会显示在浏览器窗口中。正在渲染的图像称为WebGL帧缓冲区或backbuffer。WebGL还允许额外的屏幕外帧缓冲区,这使得谈论帧缓冲区变得更加复杂,但在本文中我们忽略这一点。当前显示的图像称为frontbuffer。当然,backbuffer的内容将在某个时候复制到frontbuffer中,否则WebGL图形将不会有用户可见的效果 我们当前渲染的图像从来都不是画布上显示的图

阅读文章

WebGL从来都不是单缓冲的,这意味着当前渲染的图像永远不是当前显示在画布元素中的图像。这可确保半渲染帧永远不会显示在浏览器窗口中。正在渲染的图像称为WebGL帧缓冲区或backbuffer。WebGL还允许额外的屏幕外帧缓冲区,这使得谈论帧缓冲区变得更加复杂,但在本文中我们忽略这一点。当前显示的图像称为frontbuffer。当然,backbuffer的内容将在某个时候复制到frontbuffer中,否则WebGL图形将不会有用户可见的效果

我们当前渲染的图像从来都不是画布上显示的图像,这怎么可能呢


然后它还说,正在渲染的图像称为webGL帧缓冲区或backbuffer,正在显示的图像称为frontbuffer。有什么区别。有人能帮我解释一下这篇文章吗?

很简单。制作WebGL画布时,它有两个缓冲区,drawingbuffer也称为backbuffer,displaybuffer也称为frontbuffer

您绘制到drawingbuffer

如果你在画布上画一些东西,意味着你叫gl.clear或gl.draw???将它们设置为渲染到画布时,浏览器会将画布标记为需要合成。当前事件退出后,下次浏览器合成页面时,会将drawingbuffer复制到displaybuffer,或者交换drawingbuffer和displaybuffer

这取决于浏览器和一系列其他因素。如果设置preserveDrawingBuffer:true,则它总是将DrawingBuffer复制到displaybuffer。如果preserveDrawingBuffer为false默认值,则交换或复制取决于浏览器和一系列其他因素,但无论如何,当preserveDrawingBuffer为false时,WebGL将在交换或复制后清除drawingbuffer,以便您无法分辨差异,因此无论选择哪种,结果都是相同的

它有两个缓冲区,因为浏览器希望能够并行运行。通过这种设计,它可以随时使用displaybuffer绘制页面,因为它包含上次渲染的结果。如果没有它,如果您只有drawingbuffer并再次开始绘制,并且浏览器同时将所有元素合成在一起,那么当最终使用它时,它可能会从drawingbuffer中获得半绘制图像

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

如果preserveDrawingBuffer为false(默认值),则drawingbuffer将被清除,然后浏览器将合成页面。其效果是,每次更新时都需要绘制所有内容。你不能每一帧都画一点。如果您想看到3个圆,您需要在同一帧中绘制3个圆。这对于99%的游戏和99%的WebGL应用来说是正常的。在OpenGL、DirectX、Metal、Vulkan等系统中也是如此。在这些系统中编写的游戏也会在每一帧中绘制所有内容

如果要使用canvas.toDataURL或canvas.toBlob或gl.readPixels或任何其他方式从WebGL画布获取数据,除非您在同一事件中读取数据,否则在尝试读取数据时,它可能会被清除

换句话说,如果你这样做

function render() {
   // draw stuff with WebGL
}

function renderLoop() {
  render();
  requestAnimationFrame(renderLoop);
}

someButton.addEventListener('click', () => {
  // take screenshot
  const screenshotDataURL = webglCanvas.toDataURL();
});
屏幕截图可能会失败,因为当用户单击某个按钮时,WebGL可能已清除drawingbuffer

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

someButton.addEventListener('click', () => {

  // !!! render in the click event
  render();                 

  // take screenshot
  const screenshotDataURL = webglCanvas.toDataURL();
});
类似地,如果要在多个帧上绘制,如绘制程序,则最简单的解决方案是在创建WebGL上下文时设置preserveDrawingBuffer:true

为了增加更多的混乱,您提到了渲染缓冲区和帧缓冲区。这些都是WebGL中的特定内容

renderbuffer类似于纹理,只是它不同于纹理,它不能用作着色器的输入。它只能用作输出

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


请参见示例。

这非常简单。制作WebGL画布时,它有两个缓冲区,drawingbuffer也称为backbuffer,displaybuffer也称为frontbuffer

您绘制到drawingbuffer

如果你在画布上画一些东西,意味着你叫gl.clear或gl.draw???将它们设置为渲染到画布时,浏览器会标记为t 他画了一幅需要合成的油画。当前事件退出后,下次浏览器合成页面时,会将drawingbuffer复制到displaybuffer,或者交换drawingbuffer和displaybuffer

这取决于浏览器和一系列其他因素。如果设置preserveDrawingBuffer:true,则它总是将DrawingBuffer复制到displaybuffer。如果preserveDrawingBuffer为false默认值,则交换或复制取决于浏览器和一系列其他因素,但无论如何,当preserveDrawingBuffer为false时,WebGL将在交换或复制后清除drawingbuffer,以便您无法分辨差异,因此无论选择哪种,结果都是相同的

它有两个缓冲区,因为浏览器希望能够并行运行。通过这种设计,它可以随时使用displaybuffer绘制页面,因为它包含上次渲染的结果。如果没有它,如果您只有drawingbuffer并再次开始绘制,并且浏览器同时将所有元素合成在一起,那么当最终使用它时,它可能会从drawingbuffer中获得半绘制图像

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

如果preserveDrawingBuffer为false(默认值),则drawingbuffer将被清除,然后浏览器将合成页面。其效果是,每次更新时都需要绘制所有内容。你不能每一帧都画一点。如果您想看到3个圆,您需要在同一帧中绘制3个圆。这对于99%的游戏和99%的WebGL应用来说是正常的。在OpenGL、DirectX、Metal、Vulkan等系统中也是如此。在这些系统中编写的游戏也会在每一帧中绘制所有内容

如果要使用canvas.toDataURL或canvas.toBlob或gl.readPixels或任何其他方式从WebGL画布获取数据,除非您在同一事件中读取数据,否则在尝试读取数据时,它可能会被清除

换句话说,如果你这样做

function render() {
   // draw stuff with WebGL
}

function renderLoop() {
  render();
  requestAnimationFrame(renderLoop);
}

someButton.addEventListener('click', () => {
  // take screenshot
  const screenshotDataURL = webglCanvas.toDataURL();
});
屏幕截图可能会失败,因为当用户单击某个按钮时,WebGL可能已清除drawingbuffer

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

someButton.addEventListener('click', () => {

  // !!! render in the click event
  render();                 

  // take screenshot
  const screenshotDataURL = webglCanvas.toDataURL();
});
类似地,如果要在多个帧上绘制,如绘制程序,则最简单的解决方案是在创建WebGL上下文时设置preserveDrawingBuffer:true

为了增加更多的混乱,您提到了渲染缓冲区和帧缓冲区。这些都是WebGL中的特定内容

renderbuffer类似于纹理,只是它不同于纹理,它不能用作着色器的输入。它只能用作输出

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

有关示例,请参见