GPUImage的LookupFilter使用512x512的RGB像素图。当滤镜执行时,它会在此图像的修改版本与原始图像之间进行比较,并推断图像滤镜。
过滤器代码非常简单。这是一个摘录,所以你可以看到发生了什么:
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)));
}
}
}
}
答案 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就可以让你在红色和绿色通道中加倍颜色深度,但蓝色现在只有深度的一半。平衡三者将比仅仅加倍图像尺寸有点棘手。