В моем движке я создаю бесконечную местность с использованием алгоритма шума Perlin, рассчитанного на CPU.
Создание ландшафта происходит так:
- Если камера находится рядом с незагруженным патчем, создайте его
- Вычислить шумовой массив 513x513 с заданными границами
- Вычислить нормали, касательные, бинормальные, индексы
- Передать данные в VBO
Плюсы:
- Нужно только сделать, когда это необходимо
- Легко сделать столкновение
Против
- Медленные 64 патча 513x513 создаются за 3,1 с (одна нить). Для каждой плитки ~ 20 мс создание шума, ~ 25 мс вершины, нормали, тангенс, битангенс, индексы. Когда камера движется быстро, пользователь может заметить загрузку тайлов.
- потребление памяти ???
Теперь мне было интересно, как ускорить это, полностью создавая рельеф на GPU. Но есть некоторые сомнения:
- Если шейдеры запускают каждый кадр, не является ли эта вычислительная мощность бесполезной для вычисления шума снова и снова? Этого можно избежать, записав результат в текстуру RBGA и использовав ее позже в вершинном шейдере для смещения, но увеличивая использование памяти. С другой стороны, если создание будет очень быстрым, в памяти должны остаться только видимые плитки. Однако отсоединение буфера вызывает синхронизацию gpu-cpu, что может замедлить работу приложения (я прав?)
- Если рельеф - это просто плоская сетка, смещенная вершинным шейдером, то же самое нужно сделать на CPU, чтобы вычислить высоту и нормали в заданной точке для столкновения.
- Это всего лишь концепция, но чтобы ускорить все, я думал о проектировании сетки в области просмотра, поэтому используется только минимальное количество вершин. Как вы думаете, это будет работать?
Мой последний вопрос:
Какой лучший / самый быстрый / широко используемый метод для создания бесконечной местности на графическом процессоре?
Ответы:
Ну, если бы я попытался использовать GPU для такой вещи, я бы решил пойти на compute / opencl / cuda.
Однако независимо от использования графического процессора или процессора (что я и делаю), я бы сделал это асинхронно, решив, что вам нужен новый ландшафт, потому что текущий кадр, вероятно, слишком поздно (например, 1000 мс / 60 = 16,666 мс, и весь кадр хочет вписаться в это).
Начните генерировать (или загружать из сжатых файлов) ландшафт в рабочем потоке и делать его доступным для остальной части игры и выполнять рендеринг после того, как рабочий закончил, обычно это будет следующий кадр или, возможно, кадр после этого, поэтому пользователь на самом деле не заметит разницу, но это делает вещи более плавными.
источник