GLSL哈希表数据丢失:

时间:2019-01-24 00:51:04

标签: c++ hash glsl gpu

在上一篇文章之前,我已经遇到过尝试对事物进行哈希处理的问题:SSBO hash table, missing values我认为问题已解决,但并没有完全解决。

目标很简单,使用哈希表将3D纹理压缩到线性空间中。

我正在丢失一些数据,所以我试图进行调查:

enter image description here

(先前图像中的黑色区域缺少体素)。

我的散列函数可以创建整数,因为碰撞超过10个的任何东西都将被丢弃,因此要调查是否是这种情况,我做了以下函数:

int a_size = 100000;
void insert(vec3 pos, Voxel value)
{
    ivec3 discretized = ivec3(pos / v_size);
    int index = int(discretized.x * 73 + discretized.y * 169 + discretized.z * 8349) % a_size;
    index = (a_size + index) % a_size;

    for(int i=0; i<10; i++)
    {
        if(atomicCompSwap(voxels[index].filled, 0, 1) == 0)
        {
            if(value.position != ivec4(discretized, 1))
            {
                Voxel c_voxel = voxels[index];
                value.position = ivec4(discretized, 1);
                voxels[index] = value;

                if(i==0) {
                    voxels[index].color = vec4(1,0,0,1);
                }
                if(i==1) {
                    voxels[index].color = vec4(0,1,0,1);
                }
                if(i==2) {
                    voxels[index].color = vec4(0,0,1,1);
                }
                if(i==3) {
                    voxels[index].color = vec4(1,0,1,1);
                }
                if(i>=4) {
                    voxels[index].color = vec4(1,0,1,1);
                }
                break;
            }
        }
        index = (index * index + 7) % a_size;
    }
}

因此所有没有碰撞的体素都是红色的,有1个碰撞的体素是绿色的...

如果一个体素发生9次或更多碰撞,它将变成白色。

在另一个着色器中,我继续读取以下值:

int a_size = 100000;
vec4 fetch(vec3 pos)
{
    ivec3 discretized = ivec3(pos / v_size);
    int index = int(discretized.x * 73 + discretized.y * 169 + discretized.z * 8349) % a_size;
    index = (a_size + index) % a_size;

    for(int i=0; i<10; i++)
    {
        Voxel c_voxel = voxels[index];

        if(i>=1) {
            return vec4(1);
        }

        if(ivec4(discretized,1) == voxels[index].position)
            return voxels[index].color;

        if(voxels[index].filled == 0) return vec4(0);

        index = (index * index + 7) % a_size;
    }
}

基于此函数的逻辑,所有返回的非空值应为红色或白色。发生了多次碰撞的白色体素发生。

结果是:

enter image description here

如您所见,有几个绿色体素,没有白色体素。

在我看来,这似乎表明我的检索哈希函数实际上与存储哈希函数并不相同。如果它们是相同的,则期望没有绿色像素可见,因为这些像素对应于发生1次碰撞的体素,而这些像素将被白色覆盖。因此,要返回绿色,该函数将在第一个哈希值上返回。

两个着色器中的体素和ssbo结构的声明为:

struct Voxel
{
    int filled;
    int pad1;
    int pad2;
    int pad3;
    ivec4 position;
    vec4 normal;
    vec4 color;
};

layout(std430, binding = 0) buffer voxel_buffer
{
    uint index;
    Voxel voxels[];
};

两个散列函数对我来说似乎都是相同的。更改a_size参数也会更改丢失的匹配的比例,尽管没有特定的数字。一百万提供了最佳结果,但是90万提供了比110万更好的结果

1

0 个答案:

没有答案