Unity Compute Shader для генерации данных меша, не в состоянии вычислить все индексы треугольника.

Недавно я работал над созданием данных меша для сферической планеты, созданной из 6 подразделенных плоскостей в Unity3d ( как это). Я создал алгоритм в C#, который позволяет мне создавать сетки на процессоре, и для целей обучения я решил перенести этот алгоритм на графический процессор с помощью вычислительного шейдера. Хотя кажется, что все вершины и нормали вычисляются правильно, заполненный массив треугольников оказывается наполовину пустым, создавая нежелательный беспорядок меша.

Поскольку я рассматриваю каждую плоскость на планете как двумерную сетку вершин (даже если они деформированы в сферу), я вычисляю треугольники на процессоре, циклически изменяя ширину и высоту, принимая квадрат, созданный текущей вершиной. и 3 вершины позади и над ней (верхний левый, верхний правый, нижний левый, текущая вершина) и присвоение соответствующих индексов вершин массиву треугольников. На графическом процессоре я скопировал свой код почти строка за строкой, так как синтаксис очень похож, и все же кажется, что он останавливает вычисление треугольников после определенной точки.

Чтобы проверить, была ли это ошибка треугольников или вершин, я переписал вычисленные по GPU индексы вершин треугольников с теми, что были рассчитаны по алгоритму C#. Это дало мне форму, которую я хотел, указывая, что это действительно была проблема с моими треугольниками.

Полученные данные сетки на ЦП выглядят правильно: Правильная реализация ЦП

Сетка, сгенерированная неправильно из GPU, выглядит следующим образом: Неправильная реализация GPU

Разницу между массивом вычисленных треугольников ЦП и массивом вычисленных треугольников ГП можно увидеть на этом изображении, где графический процессор находится слева, а ЦП справа: разница в массиве треугольников

Я полагаю, что моя проблема, скорее всего, заключается в неправильном понимании того, как вычислительные шейдеры фактически выполняют свои вычисления / индексирование потоков, но может быть проблемой с моей реализацией. Любая помощь в понимании того, почему моя реализация вычислительного шейдера терпит неудачу, действительно помогла бы мне. Я включил ссылки на мой исходный код на GitHub, а не помещал здесь фрагменты кода, поскольку их может быть трудно понять вне контекста.

Исходный код реализации CPU: Исходный код

Исходный код диспетчера шейдеров GPU: Source

Исходный код для вычисления шейдера на GPU: Source

1 ответ

Решение

Вы только что сделали простую ошибку копирования / вставки здесь с количеством буферов:

ComputeBuffer vb = new ComputeBuffer (v.Length, 3 * sizeof(float)); //3 floats * 4 bytes / float
ComputeBuffer nb = new ComputeBuffer (n.Length, 3 * sizeof(float));
ComputeBuffer ub = new ComputeBuffer (n.Length, 2 * sizeof(float));
ComputeBuffer tb = new ComputeBuffer (n.Length, sizeof(int));

Измените это на это, и это должно быть хорошо:

ComputeBuffer vb = new ComputeBuffer (v.Length, 3 * sizeof(float)); //3 floats * 4 bytes / float
ComputeBuffer nb = new ComputeBuffer (n.Length, 3 * sizeof(float));
ComputeBuffer ub = new ComputeBuffer (u.Length, 2 * sizeof(float));
ComputeBuffer tb = new ComputeBuffer (t.Length, sizeof(int));
Другие вопросы по тегам