Есть несколько вещей, которые вы можете сделать, чтобы повысить производительность рисования.
Вы сказали, что они были довольно далеко. Вы можете использовать LOD, чтобы уменьшить количество вершин этих деревьев и, следовательно, уменьшить время, необходимое для прохождения всех прорисовываемых вершин. Хотя это, скорее всего, не проблема под рукой (GTX1080 с 10 000 деревьев по 200 трис в каждом, ничтожные цифры для GPU), я все же включил его. Рекламный щит - эффективный инструмент для самого низкого уровня LOD, поскольку он по сути является плоской плоскостью, всегда обращенной к камере с визуализированным изображением дерева на ней. Он теряет чувство глубины, поэтому хорошо подходит для самого низкого уровня, так как игрок, скорее всего, не заметит разницы.
Вы включили дозирование ? Динамическое пакетирование обычно выполняется автоматически, если количество вершин в сетках достаточно мало. Статическое пакетирование также можно попробовать, сделав деревья статичными, установив флажок в редакторе единиц на родительском игровом объекте. Это плохо работает с анимированными объектами. Вам нужны объекты, чтобы иметь общий материал, чтобы сделать эту работу.
Настраиваемая пакетная обработка позволяет вам управлять рендерингом, генерируя порции самостоятельно, вместо того, чтобы позволить единице обрабатывать его, а также позволяет пакетировать для больших сеток. Это легко сделать с помощью Mesh.CombineMeshes . Это также не очень хорошо работает с анимированными объектами. Вам нужны объекты, чтобы иметь общий материал, чтобы сделать эту работу. Вы, вероятно, хотите разделить свой мир на какие-то куски и создать пакеты из них. Как должны генерироваться эти фрагменты, зависит от того, как движется ваша камера в мире.
Включить инстансинг на шейдерах. Instancing позволяет движку рисовать несколько объектов (с одной и той же сеткой) всего одним вызовом рисования. Вам нужно, чтобы объекты имели общий меш и общий шейдер, чтобы это работало. Материал может варьироваться, но шейдер должен поддерживать все различные свойства.
Чтобы сделать движок лучше для создания экземпляров рендеринга, вы, вероятно, захотите сгруппировать одни и те же сетки в сцене. Также игра с очередью рендеринга материала даст вам хорошие результаты, если в одной сетке всегда один и тот же материал. Во время разработки мобильной игры, над которой я сейчас работаю, я использовал ее, чтобы уменьшить количество вызовов в моей тестовой сцене более чем наполовину. Также начиная с Unity 5.6 убедитесь, что вы отметили Enable Instancing
флажок в материале.
Сдерживайте ваши вызовы и вызовы SetPass в целом. Это необработанные вызовы для графического процессора для рисования, и у них большие накладные расходы. Уменьшение количества вызовов (что делает пакетирование и создание экземпляров) увеличит общую производительность, которую может обеспечить ваш ЦП, поскольку требуется гораздо меньше времени ожидания. Вызовы SetPass - это изменения ваших текущих шейдеров, поэтому, если у вас много разных материалов, у вас будет несколько вызовов SetPass, которые также заставляют ЦП немного подождать.
Если ваша сцена огромна и ваше процессорное время уходит на прохождение всех объектов сцены, попробуйте уменьшить количество объектов в сцене. Сгруппируйте несколько деревьев вместо того, чтобы размещать их по отдельности и собирайте их как один объект. Также убедитесь, что вы не перемещаете деревья или родительские объекты, поскольку это заставляет Unity отбрасывать кэшированные преобразования и пересчитывать все дерево сцены.
Если ваша сцена огромна, и ваше процессорное время по-прежнему в основном сводится к тому, что Unity проходит по дереву сцен, чтобы создавать списки для рендеринга всех объектов, одну вещь, которую вы можете сделать, это не позволить Unity обрабатывать рендеринг. Если у вас есть лучший способ отслеживать нарисованные объекты, вы можете использовать CommandBuffer.DrawMeshInstanced или Graphics.DrawMeshInstanced, чтобы рисовать их вручную. Я не буду вдаваться в подробности об этом, поскольку он намного более продвинутый и включает в себя отбраковку объектов самостоятельно и еще много чего.
В случае, если статическое или динамическое пакетирование не работает должным образом (что вы можете увидеть, проверив отладчик фреймов), вам необходимо убедиться, что вы действительно используете общий материал и не делаете копии материала случайно с вызовом meshRenderer.material
. Позвонив .material
, сделаем копии ваших материалов и перестанем дозировать. Используйте .sharedMaterial
вместо этого.
Начиная с Unity 5.6, вы можете использовать Отладчик фрейма, чтобы определить, почему определенные вызовы не совпали с предыдущими вызовами. Это будет очень полезно при попытке уменьшить количество вызовов вашей игры.
Instancing имеет следующие преимущества по сравнению со статическим / динамическим / настраиваемым пакетированием:
Также как недостаток, это довольно новая функция в Unity и может быть немного нестабильной. Также старые графические процессоры или мобильные устройства не обязательно поддерживают создание экземпляров.