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));