OpenGL - Как сделать много разных моделей? - PullRequest
0 голосов
/ 29 апреля 2018

В настоящее время я пытаюсь найти хороший подход для рендеринга многих (тысяч) немного разных моделей. Сама модель представляет собой простой куб с некоторым смещением вершин, представьте себе скошенную четырехугольную грань. Каждый «блок» имеет различное смещение своих вершин, поэтому в основном у меня есть воксельный движок на стероидах, так как каждый блок - не идеальный куб, а скошенный кубоид. Чтобы отобразить эту форму, необходимо 48 вершин, но их можно сократить до 24, так как видны только 3 грани. С индексированием мы находимся в 12 вершинах (4 для каждого лица).

Но теперь, когда у меня есть вершины для каждого блока в мире, как мне их визуализировать?


Что я пробовал:

  • Экстренный рендеринг. Звучит хорошо, не работает, так как мои модели не совпадают. Я мог бы упростить удаленные блоки до куба и отобразить их с помощью glDrawArraysInstanced / glDrawElementsInstanced.

  • Поместите все в одно гигантское VBO. Это имеет лучшую производительность, чем рендеринг каждого куба в отдельности, но имеет недостаток в наличии одной большой сетки. Это нежелательно, так как мне нужно, чтобы у каждого куба были разные текстуры, освещение и т. Д. Выбор одного куба внутри этой огромной сетки невозможен.

Я знаю о отборе бороздок и окклюзии, но у меня уже есть проблемы с некоторыми кубами передо мной (проверено с миром 128x128).


Мои требования:

  1. Нарисуйте несколько тысяч моделей.

  2. У каждой модели есть смещения вершин, чтобы сделать блок менее кубичным, сохраненный в другом VBO.

  3. Каждый блок должен быть отдельным объектом, так как вы должны иметь возможность размещать / удалять блоки.

Какие-нибудь хорошие советы по производительности?

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Любая приличная видеокарта (примерно с 2010 года) способна рендерить несколько миллионов вершин.

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

В случае небольшого количества изменений хранение данных в одном большом VBO или нескольких меньших VBO (и их VAO), отправка изменений в униформе и вызов нескольких glDraw *** показывает аналогичную производительность. Различные аппаратные средства ведут себя с небольшой разницей. Индексированные данные могут улучшить скорость.

Когда большая часть данных изменяется в каждом кадре, и эти изменения трудно или невозможно сделать в шейдерах, тогда ваше приложение ограничено передачей памяти. Потоковое - хороший совет.

0 голосов
/ 29 апреля 2018

Это нежелательно, так как мне нужно, чтобы у каждого куба были разные текстуры, освещение и т. Д. Выбор одного куба внутри этой огромной сетки невозможен.

Программисты должны избегать объявления, что что-то «невозможно»; это ограничивает ваше мышление.

Придание каждой грани этих кубиков разных текстур имеет множество решений. В подходе Minecraft используются текстурные атласы. Каждая «текстура» на самом деле представляет собой просто подраздел одной большой текстуры, и вы используете координаты текстуры, чтобы выбрать, какой подраздел использует конкретное лицо. Но вы можете стать более сложным.

Текстуры массива позволяют более прямо решить эту проблему. Здесь координаты текстуры будут такими же, но вы используете целое число для каждой вершины, чтобы выбрать правильную текстуру для лица. Все вершины для определенного лица будут иметь индекс. И если вы умны, вам даже не нужны текстурные координаты. Вы можете генерировать их в своем вершинном шейдере, основываясь на значениях для каждой вершины, таких как gl_VertexID и т. П.

Параметры освещения будут работать аналогично: использовать некоторые данные на каждую вершину для выбора параметров из UBO или SSBO.

Что касается бита "индивидуальный объект", это просто вопрос того, как вы думаете о проблеме. Не путайте то, что происходит в уме игрока, с тем, что происходит в вашем коде. Игры - сложная иллюзия; просто то, что что-то кажется пользователю «отдельным объектом», не означает, что оно передается вашему движку рендеринга.

Что вам нужно, так это возможность изменять данные вашего мира для удаления и добавления новых блоков. И если вам нужно показать блок как «выделенный» или что-то еще, то вам просто нужно другое значение для каждого блока (например, параметры освещения и индекс для текстуры), которое говорит вам, следует ли рисовать его как «выбранный» блок или как "невыбранный". Или вы можете просто перерисовать этот конкретный выбранный блок. Есть много способов справиться с этим.

...