Я визуализирую однопиксельные точки в текстуру uint32 с помощью вычислительного шейдера. текстура представляет собой трехмерную текстуру, x и y являются координатами области просмотра, z имеет информацию о глубине по координате 0 и дополнительные атрибуты по координате 1. Таким образом, если хотите, две созданные вручную цели рендеринга. код выглядит так:
layout (r32ui, binding = 0) coherent volatile uniform uimage3D renderBuffer;
layout (rgba32f, binding = 1) restrict readonly uniform imageBuffer pointBuffer;
for(int j = 0; j < numPoints / gl_WorkGroupSize.x + 1; j++)
{
vec4 point = imageLoad(pointBuffer, ...)
// ... transform point ...
uint originalDepth = imageAtomicMin(renderBuffer, ivec3(imageCoords, 0), point.depth);
if (originalDepth >= point.depth)
{
// write happened, store the attributes
imageStore(renderBuffer, ivec3(imageCoords, 1), point.attributes);
}
}
в то время как значения глубины верны, у меня есть несколько пикселей, где атрибуты мерцают между двумя значениями.
порядок точек в pointBuffer является случайным (но я убедился, что набор всех точек всегда один и тот же), поэтому моей первой мыслью было, что два одинаковых значения глубины могут изменить вывод, в зависимости от того, какое из них будет первым. поэтому я сделал так: if originalDepth == point.depth
он использует imageAtomicMax
, чтобы всегда иметь один и тот же из двух альтернативных атрибутов, но это ничего не изменило.
я разбросал barrier()
и memoryBarrier()
повсюду, но это ничего не изменило. Я также удалил все расходящиеся потоки управления для этого, ничего не изменив.
уменьшение размера локальной работы до 32 убирает 90% мерцания, но часть все равно остается.
Любые идеи очень приветствуются.
редактировать: прежде чем вы спросите, почему я делаю это вручную вместо использования обычной растеризации и фрагментных шейдеров, причина в производительности. растеризатор не помогает, так как я визуализирую однопиксельные точки, общая память значительно ускоряет работу, и я визуализирую каждую точку несколько раз, что потребовало от меня использования медленного геометрического шейдера.