Отсутствуют данные хеш-таблицы GLSL: - PullRequest
0 голосов
/ 24 января 2019

У меня уже были проблемы с попыткой хеширования в предыдущем посте: Хеш-таблица SSBO, пропущенные значения Я думал, что проблема была решена, но она не была полностью.

Цель проста - сжать трехмерную текстуру в линейное пространство, используя хеш-таблицу.

Я теряю некоторые данные, поэтому я пытаюсь выяснить:

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 также изменяет пропорцию пропущенных попаданий, хотя без определенного числа. один миллион дал лучшие результаты, но 900 000 дал лучшие результаты, чем 1 100 000

1 :

...