Металлический экземпляр рендеринга - несколько вопросов - PullRequest
1 голос
/ 04 октября 2019

В настоящее время я вхожу в Apple Metal API от Apple, и я не могу понять, как будет реализован рендеринг большого количества экземпляров, поскольку каждый экземпляр должен иметь свой собственный (часть) буфера.

Допустим, я хотел бы нарисовать около 50 000 экземпляров модели (что, я признаю, было бы довольно нелепо). Каждый экземпляр хранит свои данные позиционирования и анимации скелета в буфере, скажем, 50 соединений в каждом экземпляре. Теперь, учитывая, что одновременно может быть отрисовано до трех кадров, мне понадобятся эти буферы экземпляров, умноженные на количество кадров.

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

Все статьи и учебные пособия, которые я исследовал, похоже, предлагают следующее: в сцене максимальное количество объектов.

1 Ответ

2 голосов
/ 04 октября 2019

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

Instance count * joint count * elements per skinning matrix * bytes per matrix element

50,000 * 50 * 12 * 4 = 120 MB

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

Так что да, значительное количество места, но не обязательно невыполнимо. Мы можем выбрать двойную буферизацию вместо тройной буферизации, сокращая общее пространство, требуемое с 360 МБ до 240 МБ.

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

Одна из проблем здесь заключается в том, что передача 60 МБ данных скиннинга на кадр в GPU потребляет большой объем полосы пропускания. если мы работаем на дискретном графическом процессоре. Поэтому мы могли бы рассмотреть возможность переноса наших совместных расчетов в GPU. На iOS с архитектурой с разделяемой памятью это менее важно. В любом случае, мы захотим разбираться в том, как мы вычисляем нашу иерархию преобразований, так как мы собираемся делать многократное умножение, если каждое соединение перемещается в каждом кадре.

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

В качестве альтернативы, мы могли бы использовать «постраничный» подход и разделить экземпляры по нескольким буферам, каждый из которых может содержать несколько экземпляров с большим числом элементов, и которые могут быть переработаны путем однократного добавления их в пул буферов многократного использования. GPU делает рендеринг от них. Это требует разделения рендеринга на несколько вызовов отрисовки (если, возможно, мы не используем буферы аргументов), но накладные расходы на выполнение, скажем, 10 вызовов отрисовки с экземплярами, каждый с 1/10 экземплярами, будут незначительными по сравнению со временемтребуется для фактического рендеринга.

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

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

...