优化调色板映射着色器

时间:2012-08-25 20:00:25

标签: iphone opengl-es glsl

我正在尝试优化用GLSL编写的调色板映射着色器(在iPhone上运行)。我的实现肯定是天真的,但我对OpenGL完全不熟悉......以下是它的外观摘要:

#define COLOR_BLACK vec4(0.0, 0.0, 0.0, 1.0)
#define COLOR_WHITE vec4(1.0, 1.0, 1.0, 1.0)
(... total of 16 colors)

highp vec4 color = texture2D(inputImageTexture, samplePos );

highp float distances[16];
distances[0] = distance(color, COLOR_BLACK);
distances[1] = distance(color, COLOR_WHITE);
(... total of 16 distance calculations)

(... find smallest colour distance)

mediump vec4 finalColor;
if (colorDistance == distances[0]) {
    finalColor = COLOR_BLACK;
} else if (colorDistance == distances[1]) {
    finalColor = COLOR_WHITE;
(... total of 16 comparisons)

gl_FragColor = finalColor;

这很好但但速度很慢。我确定我没有在这里有效地使用OpenGL:)

任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:2)

在最近的过滤模式中使用(小)3D纹理作为查找表。

由于评论而更新

如果3D纹理不可用,您可以使用一个较大尺寸的1D纹理,再次使用最近的过滤模式,并以与平面阵列中相同的方式处理3D纹素,即

texel_index(x,y,z) = x*width*height + y*width + z;

答案 1 :(得分:1)

实现这种效果的另一种方法是通过圆角/地板。所以你得到(未经测试):

highp vec4 color = texture2D(inputImageTexture, samplePos );
gl_FragColor = floor(color*2.0) * 0.5;

您可能想要使用因子2。

答案 2 :(得分:0)

您要映射到哪种调色板?它只是十六种随机颜色还是有一种模式?

假设16种颜色是八种颜色加亮或暗,那么你可以将输入的RGB转换为YUV(或任何其他亮度导向的空间),在Y通道上做出一个判断,然后将UV转换为通过单个纹理查找进行2d测试。如果打开或关闭红色,绿色和蓝色的八种颜色,那么您可以在不进行查找的情况下进行二维测试。

如果你只是想要一个独立的外观,那么像Jaxan的内部组件可能是最聪明的事情。