0

我正在尝试优化用 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 :)

任何帮助表示赞赏!

4

3 回答 3

2

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

因评论而更新

如果 3D 纹理不可用,您可以使用更大尺寸的 1D 纹理,再次以最近的过滤模式,并以与在平面数组中处理它们相同的方式处理 3D 纹素,即

texel_index(x,y,z) = x*width*height + y*width + z;
于 2012-08-25T20:02:26.170 回答
1

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

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

您可能想玩弄因素 2。

于 2012-08-25T20:09:44.700 回答
0

您要映射到哪种调色板?它只是十六种随机颜色还是它们有图案?

假设这 16 种颜色是八种颜色加上亮或暗,那么您可以将传入的 RGB 转换为 YUV(或任何其他面向亮度的空间),在 Y 通道上进行单一判断,然后通过以下方式将 UV 转换为 2d 测试单个纹理查找。如果红色、绿色和蓝色的八种颜色打开或关闭,则无需查找即可进行 2d 测试。

如果你只是想要一个离散的外观,那么像 Jaxan 的rounding-within-components 可能是最聪明的事情。

于 2012-08-25T20:16:38.670 回答