Экземпляр повышает производительность (значительно) при одновременном рендеринге нескольких копий одного и того же меша. Но сколько накладных расходов это имеет при рендеринге ровно одной копии одним вызовом отрисовки? Будет ли хорошей или плохой идеей использовать инстансинг для всей геометрии, отображаемой движком?
Изменить: скажем, мы создаем игру FPS. У большинства объектов есть только один экземпляр: нож, пистолет, пулемет, здание и радиовышка. Но есть также несколько объектов с несколькими экземплярами: деревья (например, 3 вида деревьев с сотнями экземпляров), трава и т. Д. Я имею в виду: вместо того, чтобы визуализировать объекты с одним экземпляром «традиционным» способом и деревья и трава, используя инстансинг, мы рендерим их все, используя инстансинг Таким образом, наша радиомачта имеет только один экземпляр (чью информацию мы храним в буфере данных экземпляра), и мы визуализируем эту башню, используя какой-то DrawInstanced()
вызов с равным количеством экземпляров 1
. То же самое со всеми другими объектами (конечно, деревья и трава имеют несколько экземпляров).
Поэтому мой вопрос: плохая идея нарисовать один экземпляр объекта с использованием инстансинга? Есть ли у экземпляра слишком много накладных расходов (с точки зрения памяти и производительности) или это каким-то образом нежелательно для рендеринга объектов с одним экземпляром?
источник
(В моей системе это нигде не проверялось). В GL создание единственного меша (рисование с count = 1) имеет некоторые неприятные накладные расходы, но я не знаю, откуда это взялось. Я настоятельно рекомендую не делать этого.
Я проверил это в практическом приложении пару месяцев назад. Я кодировал некоторые глобальные алгоритмы освещения в сцене Crytek Sponza, которая состоит примерно из 350 или около того ячеек (точно не помню), из которых пара делит несколько примеров. В начале я сделал это так, как вы предлагаете, просто скопируйте все и нарисуйте остальное с количеством экземпляров 1, поскольку это немного упростило код рендеринга.
Позже, когда я оптимизировал рендерер, просто переключившись с создания экземпляров объектов count = 1 и отправив их обычным способом, я сэкономил около 3,5 миллисекунд на кадр на i7 3770k (и GTX 770). Переключение ячеек с несколькими экземплярами на выполнение их традиционным способом сэкономило мне еще 0,5 мс. В целом приложение выросло с ~ 120 FPS до ~ 230 FPS.
Эти цифры, конечно, всегда зависят от того, где узкие места в вашем приложении, и последние 0,5 мс могут фактически стать замедлением в приложении, где вы сильно привязаны к вызову. Но в остальном, по моему опыту, у инстансинга есть некоторые неприятные накладные расходы, если вы не рисуете много вещей одновременно.
источник
Вы можете быть уверены, что рисование одного экземпляра объекта обходится дороже, чем обычное рисование одного объекта. Для создания экземпляров GPU готовит большое количество объектов, и эта подготовка будет отличаться, чем для одного объекта. Однако насколько велика эта разница в производительности, можно узнать только экспериментально, и она очень сильно зависит от вашей фактической настройки рендеринга. Единственный способ узнать наверняка - это проверить его самостоятельно. Сложно провести сравнительный анализ одного колла, вот несколько идей о том, как вы могли бы продолжить.
источник
Прошло 4 года ... и я думаю, что можно с уверенностью сказать, что это прекрасно, когда вы отправляете вызовы "экземпляра" с 1. Как вы могли заметить, оба новых API DX12 и Vk имеют количество экземпляров, которое может быть от 0 до NUM_INSTANCES . Также обратите внимание, что нет DrawIndexed (...) .
РЕДАКТИРОВАТЬ
В качестве предостережения, вышеприведенное, вероятно, подходит для этих современных API, возможно, использование чего-то старого, такого как Gl <3.3, или, возможно, DX11 потребует некоторого профилирования, как упоминали другие пользователи.
источник