Столкновение частиц с миром вокселей в вычислительном шейдере

Я добавил систему частиц в воксельную игру, над которой я работаю. На данный момент вся физика выполняется на процессоре, и он довольно медленный (мой процессор борется с 2000 частицами).

Для каждой частицы я определяю диапазон вокселей, с которыми она теоретически может столкнуться (на основе положения и скорости частицы, а также прошедшего времени), а затем проверяю наличие столкновений со всеми вокселями в этом диапазоне и использую ближайшее столкновение.

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

Если я конвертирую свой мир вокселей в битовый массив и добавляю его в SSBO, тогда вычислительный шейдер будет иметь всю геометрическую информацию, необходимую для обнаружения столкновений. Тем не мение...

Код обнаружения столкновений, который я написал для ЦП, вообще не будет эффективен на ГП; там просто много разветвлений / циклов. Есть ли эффективный способ столкновения частиц с сеткой вокселей в вычислительном шейдере?


person Mr. Smith    schedule 06.06.2019    source источник


Ответы (1)


Для упрощения рассмотрите свои частицы как точечные объекты только с положением P и скоростью V единиц / тик. Вместо того, чтобы точно вычислять, с какими вокселями будут касаться ваши частицы, первое приближение для движения частицы может заключаться в том, чтобы просто проверить, занято ли P + V сплошным вокселем (с использованием 3D-сэмплера), и установить V равным нулю (или доле сам), если это так, в противном случае увеличьте P на V. Эти условные операции могут быть эффективно выполнены с помощью целочисленной арифметики, никакого ветвления не требуется.

Если это приближение слишком грубое, потому что V часто имеет длину в несколько единиц вокселей, и поскольку ваша геометрия вокселей достаточно хороша, чтобы частицы могли проходить сквозь твердые стены, вы можете просто повторить описанную выше операцию N раз внутри шейдера, используя V / N вместо V, где N должно быть наименьшим постоянным целым числом, которое заставляет обрезку останавливаться большую часть времени. Циклы for постоянной длины будут разворачиваться компилятором шейдера, поэтому вам по-прежнему не потребуется истинного ветвления.

Теперь с этим алгоритмом поведение ваших частиц будет заключаться в прекращении всего (или большей части) движения, как только они достигнут препятствия. Если на них действует гравитация (лучше всего это делать внутри шейдера), они упадут прямо вниз, но только после потери своей вертикальной скорости. Достигнув этажа, они останутся на месте.

Если вы хотите, чтобы ваши частицы скользили по горизонтальным поверхностям вместо того, чтобы останавливаться там, где они приземляются, и сохраняли свой вертикальный импульс при столкновении со стенами, вы можете разделить V на горизонтальный и вертикальный компоненты и выполнить вышеуказанные шаги отдельно для двух компонентов.

У вас также есть возможность разделить все три координаты V, чтобы частицы, ударяющиеся о стены с диагональным горизонтальным движением, следовали за стеной, а не падали прямо вниз, но снижение производительности может перевесить преимущества по сравнению с двумя компонентами.

person Magma    schedule 07.06.2019