WebGL中的栅格操作(ROP)(无glLogicOp)

时间:2015-04-14 07:53:57

标签: javascript graphics webgl opengl-es-2.0 gpu-programming

问题:

使用WebGL,在屏幕缓冲区上绘制位图的最有效方法是什么,因为必须对每个像素/片段执行光栅操作?绘制调用之间的栅格操作可能不同。

背景:

作为我正在开发的应用程序的一部分,我必须开发一个用于将位图复制到目标缓冲区的函数。位图可以小于画布,并使用X和Y坐标的偏移来放置。此外,给定ROP代码,可以在复制位图时执行光栅操作。可以找到完整的ROP列表here

在OpenGL ES 1.x中,有一个名为glLogicOp()的函数可以在绘制时执行所需的二进制操作。但是,由于WebGL基于OpenGL ES 2.0,因此该功能不存在。我还想不出一个解决这个问题的直接方法。我有一些想法,但我不相信他们会提供最佳表现。

可能的解决方案:

  1. 通过使用带有屏幕外缓冲区颜色数据的类型化数组来执行Javascript中的ROP。然而,这将依赖于CPU来计算每个像素的ROP。在绘制时,我会将屏幕外数据上传到纹理,并使用简单的着色器在屏幕外缓冲区上绘制。
  2. 使用here描述的乒乓结构技术。有两个纹理我可以从一个采样并在另一个上写,但是,我会被迫在每次绘制调用时绘制整个屏幕外缓冲区,即使要绘制的位图仅覆盖画布的一小部分。可能的优化是仅在使用依赖于目标像素的ROP时切换纹理。
  3. 在需要ROP依赖于目标像素的绘制调用之前,使用readPixels()从屏幕外缓冲区读取数据。读取位图的像素数据被读取,上传到纹理并与位图本身一起传递到着色器以用于采样。然而,readPixels函数被认为是最慢的WebGL函数之一,因为它需要CPU和GPU之间的同步。
  4. 修改

    使用ping post纹理技术,我想每次都必须绘制整个屏幕,因为对于每个绘图,为了正确地采样目标像素,我需要表示当前的屏幕外(绘图前的屏幕) 。除非我每次都画出整个画面,否则两种纹理只会代表替代图画而不是真实的屏幕外图像。

    在视觉上更容易展示,但请考虑以下示例:

    1)我在屏幕的左半部分绘制一个矩形,第一次绘制调用将tex1作为采样源,将tex2作为绘图目标。

    2)我在屏幕的右半部分绘制矩形,第二次绘制调用将tex2作为采样源,将tex1作为绘图目标。

    3)当我尝试在下一次绘制调用时在整个屏幕上绘制一条水平线时,由于tex1(source)不包含第一次绘制调用中绘制的矩形,因此将从屏幕的左侧部分进行采样目的像素的颜色错误。

0 个答案:

没有答案