You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GLSL中高效查询给定RGB值是否属于预存颜色列表

原大数组方案不可行的原因

你尝试的16777216长度的bool数组方案从硬件限制层面就无法实现:GLSL shader的可用内存非常有限,单个数组占用空间超过几十KB就可能触发编译/运行错误,16M大小的数组远远超出了所有GPU的shader内存限制,且GLSL不允许在全局作用域对数组做单元素赋值,所有const数组必须在定义时完成初始化。

最优兼容方案:排序+二分查找

这个方案不需要复杂的预处理,兼容性拉满,性能相比原遍历方案提升40倍以上,仅需最多9次循环即可完成查询:

  1. 预处理阶段(CPU端完成):将你的384个RGB值用你写的rgbHash函数转换为24位整数,然后将这384个整数从小到大排序,得到排序后的整数列表。
  2. GLSL代码实现:
// 替换为你CPU端预处理好的排序后的384个哈希值
const int sortedRgbHash[384] = int[384](
    1234, 2345, 3456, /* 其余值按排序结果填充 */
);

int rgbHash(int r, int g, int b) {
    return (r << 16) | (g << 8) | b;
}

bool cExists(int r, int g, int b) {
    int target = rgbHash(r, g, b);
    int low = 0;
    int high = 383;
    while (low <= high) {
        int mid = (low + high) / 2;
        if (sortedRgbHash[mid] == target) {
            return true;
        } else if (sortedRgbHash[mid] < target) {
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    return false;
}

极致性能方案:1D纹理实现O(1)查询

如果你的运行环境支持GLSL 300 es及以上/桌面GLSL 130及以上,可以用1D纹理实现无循环的O(1)查询:

  1. 预处理阶段(CPU端完成):创建一张长度为512的R8_UNORM格式1D纹理,对384个RGB值计算最小完美哈希映射到0-383的索引,对应纹理位置的值设为255,其余位置设为0。最小完美哈希的生成可以用现成的工具完成,384个元素的生成成本极低。
  2. GLSL代码实现:
uniform sampler1D u_RgbLookup;

// 替换为你生成的最小完美哈希函数
int minimalPerfectHash(int r, int g, int b) {
    // 示例逻辑,实际由CPU端生成的哈希规则替换
    return ((r * 123 + g * 456 + b * 789) % 512);
}

bool cExists(int r, int g, int b) {
    int idx = minimalPerfectHash(r, g, b);
    float val = texture(u_RgbLookup, float(idx) / 512.0).r;
    return val > 0.5;
}

注意事项

如果传入的RGB是归一化的0-1浮点值,转换为整数时需要用int(round(r * 255.0))处理,避免浮点精度误差导致匹配失败。

内容的提问来源于stack exchange,提问作者Benny F.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:45:00