GLSL:是否可以创建包含中心像素的单色区域的蒙版?

时间:2012-10-03 23:47:02

标签: ios opengl-es opengl-es-2.0 glsl flood-fill

我希望在我的iPhone应用程序中使用GLSL着色器(从相机捕获图像)在Photoshop中创建像“Magic Wand”这样的效果,用于屏幕的中心像素。现在我通过获取像素数组并为中心像素应用某种泛洪填充算法(所有使用Objective-C代码)来实现这一点。这是在CPU上执行的,对我来说这有点太慢了,所以我想尝试使用GLSL着色器。

实际上,我需要的是重写碎片着色器中的泛洪填充,更确切地说,要知道当前片段的颜色是否接近阈值颜色,以及当前片段是否是先前检测到的区域中的片段的邻居。这对我来说听起来太混乱了,我甚至无法理解它是否可能。

泛洪填充算法是(伪代码):

Flood-fill (node, target-color, replacement-color):
 1. Set Q to the empty queue.
 2. If the color of node is not equal to target-color, return.
 3. Add node to Q.
 4. For each element n of Q:
 5.     If the color of n is equal to target-color:
 6.         Set w and e equal to n.
 7.         Move w to the west until the color of the node to the west of w no longer matches target-color.
 8.         Move e to the east until the color of the node to the east of e no longer matches target-color.
 9.         Set the color of nodes between w and e to replacement-color.
10.         For each node n between w and e:
11.             If the color of the node to the north of n is target-color, add that node to Q.
12.             If the color of the node to the south of n is target-color, add that node to Q.
13. Continue looping until Q is exhausted.
14. Return.

问题:是否可以在着色器中执行此操作,如果是,我该怎么办?

谢谢!

1 个答案:

答案 0 :(得分:3)

不,着色器不会那样工作。在着色器中,您始终只能读取或写入,而不能同时读取或写入。如果你回头看看你的算法,它会读取和写入相同的数据。

你可以试试乒乓球计划,但我怀疑它会很快:

for ( sometime )
  for (every pixel in dest) 
    if source has filled neighbours (up,left,top,bottom) and is above threshold, then write fill
    else write source
  flip source and dest

这将在每次迭代时更多地执行一个像素 - 但是在完成时(图像大小)只有一个上限。

你可以更聪明地尝试做一些金字塔计划:首先以低2倍的分辨率运行并使用它来确定填充区域。但它实际上并不是一种在GPU上运行良好的算法。我建议改为使用手动优化的装配CPU版本。