找出纹理在WebGL中是否包含至少一个黑色像素?

时间:2015-03-19 21:22:32

标签: three.js glsl webgl shader

是否有特殊的webGL技巧来检查纹理是否包含至少一个黑色rgb像素,而不必读取CPU上的像素?

对我来说,检查CPU上的像素似乎是唯一的解决方案。在这种情况下, 有没有办法,例如,将高分辨率纹理压缩为包含单个布尔颜色信息的1x1纹理,这样我出于性能原因只需读取一个像素。

谢谢!

2 个答案:

答案 0 :(得分:0)

只有我的想法才是......至少是复杂的。

假设我们的纹理尺寸为N,那么:

  • 使画布1x1像素大。
  • 创建N * N个点的数组,每个点都有不同的[x,y]属性,表示我们要查找的像素位置。
  • 在顶点着色器中,根据点位置进行纹理查找。如果该像素的颜色不是黑色,则为discard;
  • 设定点位置[0,0]
  • 在片段着色器中,只需绘制黑色(假设我们有白色画布)。

然后你有的是1x1帆布,黑色,如果有黑色像素,或白色,如果没有,你可以简单地用CPU读取它。

这种情况下的瓶颈是第二步=点阵构建,也是cpu-gpu通信。只有当您需要在短时间内完成大量读取并且在应用程序运行之前知道纹理的大小时,这将运行得更快,因此您可以为所有纹理重用相同的缓冲区。

答案 1 :(得分:0)

只是想法,不确定它是否会起作用。

制作渲染目标,使用着色器绘制纹理,如果像素为rgb 0,0,0则绘制白色,否则为黑色。我们假设是1024x768,现在有1个白色像素。将其绘制成1/4尺寸的纹理。在这种情况下512x384。如果我们有最坏的情况,只有1个白色像素,然后它将平均为0.25(63)。我们可以再做2次,先是256x192,然后是128x96。那个原始的白色(255)像素现在将是(3)。因此,再次运行黑/白着色器并重复64x48,32x24,16x12,运行黑/白着色器,然后再次运行8x6,4x4,2x2,运行黑/白着色器。然后1x1。现在检查如果那不是纯黑色,那么至少有一个黑色像素。

每次通过平均着色器中的一堆像素,尝试将这3个级别减少为1,而不是减小1/2的大小。例如15x15像素仍会留下一些> 0如果只有1个像素是白色而其余像素是黑色。在那种情况下,从1024x768开始,它将是

1024x768 -> 67x52 -> 5x4 -> 1x1

我不知道这会更快还是更慢。