我正在尝试优化用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:)
任何帮助表示赞赏!
答案 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的内部组件可能是最聪明的事情。