android - 如何创建一个从查找表映射颜色的简单片段着色器?
问题描述
我正在尝试为我的 Android 应用程序创建像 Instagram 这样的图像过滤器。我是图像处理的新手,刚刚偶然发现了这个称为颜色映射的术语。经过大量研究,我尝试使用 OpenGL 使用查找表 (LUT) 创建自己的过滤器。但是在将滤镜添加到相机后,结果如下:
你可以看到我的拇指边缘有一种奇怪的蓝色。它只发生在图像的过度曝光区域。
这是片段着色器代码:
#extension GL_OES_EGL_image_external : require
precision lowp float;
varying highp vec2 vTextureCoord;
uniform samplerExternalOES inputImage;
uniform sampler2D lookup;
void main() {
vec2 tiles = vec2(8.0);
vec2 tileSize = vec2(64.0);
vec4 texel = texture2D(inputImage, vTextureCoord);
float index = texel.b * (tiles.x * tiles.y - 1.0);
float index_min = min(62.0, floor(index));
float index_max = index_min + 1.0;
vec2 tileIndex_min;
tileIndex_min.y = floor(index_min / tiles.x);
tileIndex_min.x = floor(index_min - tileIndex_min.y * tiles.x);
vec2 tileIndex_max;
tileIndex_max.y = floor(index_max / tiles.x);
tileIndex_max.x = floor(index_max - tileIndex_max.y * tiles.x);
vec2 tileUV = mix(0.5/tileSize, (tileSize-0.5)/tileSize, texel.rg);
vec2 tableUV_1 = tileIndex_min / tiles + tileUV / tiles;
vec2 tableUV_2 = tileIndex_max / tiles + tileUV / tiles;
vec3 lookUpColor_1 = texture2D(lookup, tableUV_1).rgb;
vec3 lookUpColor_2 = texture2D(lookup, tableUV_2).rgb;
vec3 lookUpColor = mix(lookUpColor_1, lookUpColor_2, index-index_min);
gl_FragColor = vec4(lookUpColor, 1.0);
}
这是查找表。这是一个基本查找表。我尝试编辑查找表并应用过滤器,但结果是相同的,与表无关。
是什么导致了这个问题?谁能告诉我如何创建一个简单的片段着色器,将颜色从查找表映射到当前纹理?任何帮助,将不胜感激。问候。
这是加载纹理的代码:
public static int loadTexture(final Bitmap img) {
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img, 0);
return textures[0];
}
解决方案
不确定您的外部采样器正在使用什么色彩空间或伽玛,但看起来您正在获取零到一范围之外的输入值,因此过度暴露的区域正在跳过 LUT 平铺边界。
作为诊断,将您的输入限制在 0 和 1 之间,但这很少是正确的“正确修复”,因为颜色的裁剪会很明显。
像这样的东西:
vec4 texel = texture2D(inputImage, vTextureCoord);
texel = min(texel, 1.0);
推荐阅读
- javascript - 为什么我的输入参数在此代码段中被修改?
- mysql - 如何检查 MySql 中缺少的时间戳
- smtp - 为什么 SMTP API 可以使用任何发件人地址?如何将我的电子邮件列入黑名单?
- javascript - 从 HTML 中删除 JS 代码后,从内存中删除 JS 函数和事件
- reactjs - 扩展airbnb时如何在eslint中启用绝对导入?
- android - 使用导航组件通过后退按钮向上导航
- excel - vba - 如何根据找到定义的变量的次数进行编码
- python - 自 Spyder 升级以来 Python 崩溃
- rsync - Rsync 复制“不安全”的符号链接,但不更新符号链接目标的修改时间
- ios - 将类名称添加到视图控制器时 Segue 不起作用