У меня уже были проблемы с попыткой хеширования в предыдущем посте: Хеш-таблица SSBO, пропущенные значения Я думал, что проблема была решена, но она не была полностью.
Цель проста - сжать трехмерную текстуру в линейное пространство, используя хеш-таблицу.
Я теряю некоторые данные, поэтому я пытаюсь выяснить:
(в черных областях на предыдущем изображении отсутствуют воксели).
Моя хеш-функция может создавать такие целые, поскольку все, что содержит более 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;
}
}
Исходя из логики этой функции, все возвращаемые непустые значения должны быть красного или белого цвета. Белые вокселы, обозначающие более одного столкновения, произошли.
Результат:
Как вы можете видеть, есть пара зеленых вокселей и нет белых вокселей.
Мне кажется, это указывает на то, что моя хэш-функция для поиска не идентична моей хэш-функции для хранения. Если бы они были идентичны, ожидалось, что зеленые пиксели не будут видны, так как эти пиксели соответствуют вокселям с 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 :