GPUImage查找过滤器 - 创建大于512²颜色的颜色深度

时间:2016-10-04 22:15:15

标签: ios macos opengl-es gpuimage

GPUImage的LookupFilter使用512x512的RGB像素图。当滤镜执行时,它会在此图像的修改版本与原始图像之间进行比较,并推断图像滤镜。

enter image description here

过滤器代码非常简单。这是一个摘录,所以你可以看到发生了什么:

void main()
 {
     highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);

     highp float blueColor = textureColor.b * 63.0;

     highp vec2 quad1;
     quad1.y = floor(floor(blueColor) / 8.0);
     quad1.x = floor(blueColor) - (quad1.y * 8.0);

     highp vec2 quad2;
     quad2.y = floor(ceil(blueColor) / 8.0);
     quad2.x = ceil(blueColor) - (quad2.y * 8.0);

     highp vec2 texPos1;
     texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
     texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);

     highp vec2 texPos2;
     texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
     texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);

     lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1);
     lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2);

     lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));
     gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity);
 }
);

查看过滤器映射依赖于512x512图像的位置?

我正在寻找使用1024x1024源图像的方法来获得4倍的颜色深度,但我不确定这个查找过滤器图像最初是如何生成的。

可以在代码中生成这样的内容吗?如果是这样,我意识到这是一个非常广泛的问题,但我该怎样做呢?如果无法在代码中生成,我有哪些选择?

-

更新

原来LUT生成代码一直包含在头文件中。这里有问题的部分来自头文件:

  

查找纹理被组织为8x8四边形64x64像素,代表所有可能的RGB颜色:

64x64如何映射所有可能的RGB通道? 64³= 262,144,但它只占RGB假定的24位容量的1/64,即64³(16,777,216)。这里发生了什么?我错过了这个LUT的工作方式吗?我们如何只用1/64的数据来计算所有可能的RGB颜色?

for (int by = 0; by < 8; by++) {
   for (int bx = 0; bx < 8; bx++) {
       for (int g = 0; g < 64; g++) {
           for (int r = 0; r < 64; r++) {
               image.setPixel(r + bx * 64, g + by * 64, qRgb((int)(r * 255.0 / 63.0 + 0.5),
                                                             (int)(g * 255.0 / 63.0 + 0.5),
                                                             (int)((bx + by * 8.0) * 255.0 / 63.0 + 0.5)));
           }
       }
   }
}

2 个答案:

答案 0 :(得分:1)

我不太确定你实际遇到了什么问题。当你说你想要“4倍颜色深度”时你的意思是什么。颜色深度通常表示每个颜色通道(或每个像素)的位数,这完全独立于图像的分辨率。

就查找表精度(取决于分辨率)而言,假设您使用来自原始纹理的双线性滤波纹理输入,并将过滤后的查找转换为变换表,那么您已经在查找表中的样本之间进行线性插值。颜色通道的插值精度高于存储格式;例如通常为fp16等效,即使是以每像素8位存储的纹理。

除非您的颜色转换中存在大量的非线性(不常见),否则在查找表中添加更多样本不太可能对输出产生显着影响 - 插值已经做得相当不错填补空白。

答案 1 :(得分:1)

Lev Zelensky provided the original work for this,所以我对内部的工作原理并不熟悉,但你可以看一下在着色器中执行的数学运算,以了解正在发生的事情。

在512x512查找中,您有一个8x8的单元格网格。在这些单元格中,您有一个64x64图像补丁。红色值在该补丁中从左到右从0到255(标准化值为0.0到1.0),绿色值从0到255下降。这意味着红色有64个步骤,绿色有64个步骤。

然后,当您沿着补丁向下,从左到右,从上到下,每个单元格都会增加蓝色值。使用64个补丁,可以为您提供64个蓝色值,以匹配64个红色和绿色。这样可以在所有通道中对RGB值进行相等的覆盖。

因此,如果您想将色阶数量加倍,则必须将色块大小加倍至128x128并具有128个网格。由于128没有整数平方根,所以它必须更像是一个矩形。只需要1024x1024就可以让你在红色和绿色通道中加倍颜色深度,但蓝色现在只有深度的一半。平衡三者将比仅仅加倍图像尺寸有点棘手。