Tergan-ural.ru

Терган Урал
4 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Пиксельный Lo-fi в Unity

Пиксельный Lo-fi в Unity.

Efim Sirotkin

Визуальный стиль моей находящейся в разработке игры LAUNDRY GAME (да, это бессовестная реклама) основан на больших чётких пикселях в 3D. Я обожаю 3D в низком разрешении. Мне задавали много вопросов о том, как я это сделал, поэтому я решил написать туториал.

Примечание: это только моё решение! Существуют способы с применением шейдеров, блиттингом графики и другими трюками, но для моего небольшого соло-проекта такого решения оказалось вполне достаточно.

Дополнение 1: умный парень Пит Брисбёрн отправил сюда скрипт на случай, если вам не понравится трюк с «quad в небе» (этапы 4–6)!

Этап 1: подготовка исходной сцены

Для начала нужно подготовить сцену! Я создал этот небольшой куб с моим другом-птицей Oscar J. Ruffles. Он бегает по кубу и постоянно кричит. (Это всего лишь соединённые вместе контроллер персонажа и аниматор.)

Но взгляните на эти отвратительные линии сглаживания! Фу, давайте избавимся от них.

Этап 2: убираем MSAA камеры

Выделите Main Camera и снимите флажок в поле Allow MSAA. Как видите, пиксели становятся намного чётче. Но пока нет увеличения масштаба (upscaling)! То есть все пиксели будут маленькими. Нужно это исправить.

Этап 3: рендеринг камеры в Render Texture

Увеличиваю масштаб я (чтобы получить огромные чёткие пиксели) при помощи RenderTexture и рендеринга Main Camera в эту текстуру. Это позволит нам использовать эту RenderTexture как любую обычную текстуру!

Вот параметры, которые я буду использовать для своей RenderTexture. Size — это размер, с которого мы увеличиваем масштаб. Чем меньше число, тем больше пиксели. Я для обоих значений обычно использую числа в интервале от 300 до 600 (превосходная Celeste, например, выполняет увеличение масштаба с 320×200).

Filter Mode — это способ выполнения увеличения/уменьшения масштабирования (up/downscaling). Режим «Point» не добавляет сглаживания, то есть сохраняет чёткость пикселей, которая нам так нужна.

Но что произошло?

Теперь мы рендерим Camera не на экран, а в RenderTexture, поэтому на экране ничего не рендерится!

Чтобы это исправить, нам нужно настроить ещё одну камеру, но на этот раз немного иначе.

Этап 4: создание повышающей масштаб камеры + Quad

Начнём с того, что создадим в сцене новую камеру (назовём её QuadCamera) и как дочерний объект прикрепим к ней 3D quad.

Этап 5: разместим его где-нибудь в пустоте

Затем нам нужно взять QuadCamera и засунуть её куда-нибудь. Не важно, куда, главное, чтобы её никогда не было видно из Main Camera. Я обычно поднимаю её высоко в небо или опускаю глубоко вниз.

Этап 6: прикрепляем Render Texture к Quad и размещаем его перед камерой

Затем мы берём quad. Я задал для него материал “Sprites-Default” (стандартный материал Unity, на который не действует освещение), чтобы на него не влияло никакое случайное освещение в сцене. Затем перетащим RenderTexture на quad. Теперь quad показывает нашу сцену! Затем мы перемещаем quad так, чтобы он находился перед QuadCamera (камерой, которая теперь рендерит целевой экран).

Как видите, теперь масштаб рендеринга увеличен! Оскар может постоянно щёлкать своим пиксельным клювом! Но в то же самое время мы стали намного ближе к его голове.

Этап 7: регулируем камеры

На последнем этапе вернёмся к моей Main Camera и настроим её так, чтобы мы видели примерно то же, что и раньше. Здесь можно увеличить размер render texture, чтобы пиксели стали немного меньше, или уменьшить его,, чтобы на экране помещалось всего 7 пикселей. Это время для экспериментов, найдите то, что подходит лично вам.

Читайте так же:
Тильда курица к пасхе сшить

Бонус: сделаем так, чтобы текстуры не были размытыми

Как мы видели, текстура модели (большой глаз Оскара) всё это время была размытой. Так получилось потому, что при импорте текстур в Unity выбираются стандартные параметры для генерации mip-текстур и плавного масштабирования. Но нам этого не нужно. Поэтому при импорте текстур необходимо отключить Generate Mip Maps и выбрать для Filter Mode режим Point.

На этом пока все, надеюсь, вам было очень интересно проследить за мной и научится работать с пикселями в Unity. Я очень люблю 3D в низком разрешении, в этом есть своя изюминка. Успехов!

Unity2D: делаем самый быстрый шейдер для background спрайта

Очень часто, при создании почти каждой 2D игры, нам нужно положить на весь background одну картинку, или градиент, которые будут выступать фоном игры или определенной сцены. Как правило, для этого мы просто ставим спрайт и накладываем текстуру.

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

Хочу показать вам вариант с разбором непрозрачного шейдера спрайта, без возможности менять цвет и альфу с минимальным функционалом:

Разбираем:

#3 Убираем прозрачность. Стандартная прозрачность это код для каждого пикселя на экране вида:

где lerp это 3 раза для 3-х компонентов rgb:

#4 Убираем PIXELSNAP_ON (уменьшает варианты компиляции шейдера), который тянет за собой для каждого вертекса:

#5 Убираем ETC1_EXTERNAL_ALPHA (еще уменьшает варианты компиляции шейдера), который добавляет для каждого вертекса:

#6 Убираем флип UV на шейдере. В новых версиях юнити флип спрайта работает на уровне вершин при подготовке меша, и код в риалтайме, как по мне — забытый излишек:

#7, #9 и #10 Убираем на вершинном шейдере 2 уножения на цвет (8 умножений float), убираем умножение на пиксельном шейдере на цвет (4 умножения флоат на каждый пиксель) и убираем alpha fade (3 умножения флоат на каждый пиксель):

Результаты тестов на Xiaomi Redmi Note 4 (1920×1080):

На все тесты влияет вертикальная синхронизация телефона! На всех тестах N спрайтов на весь экран телефона.

Тест №1: 1 спрайт. Оба вариант не падают ниже 60 fps

Тест №2: 10 спрайтов. Дефолтные спрайты прыгают между 30-60 fps. Оптимизированные стабильно 60 fps

Тест №3: 20 спрайтов. Дефолтные стабильно 20 fps. Оптимизированные стабильно 30 fps.

Тест №4: 30 спрайтов. Дефолтные стабильно 15 fps. Оптимизированные прыгают между 20-30 fps.

Тест №5: 40 спрайтов. Дефолтные прыгают между 10-12 fps. Оптимизированные между 15-20 fps.

Тест №6: 50 спрайтов. Дефолтные стабильно 10 fps. Оптимизированные прыгают между 12-15 fps.

001

Тесты не могут быть точными из-за профайлинга, лимита в 60fps, вертикальной синхронизации и вывода текста на экран.

Примечания:

Если вы используете цвет для подкраски спрайта, то просто верните пункты #5, #9 и №10.

Если вам нужен Pixel Perfect Snapping, то верните пункты №4 и #8

Если ваш background спрайт всегда не прозрачен и рисуется на весь экран, то есть смысл у вашей камеры поставить Clear Flag — Depth Only, вместо Solid Color (по умолчанию). Тогда каждый новый кадр, перед начало отрисовки кадра, камера не будет заливать весь экран цветом (что занимает время).

Если вы не используете сложные эффекты пост обработки, то есть смысл у камеры отключить опцию Allow HDR. Это сильно сэкономит память.

Читайте так же:
Как сшить покрывало на кровать виды изделий тканей

Рекомендации к применению:

Создайте несколько шейдеров на разные случаи жизни. Не только для background. Это могут быть прозрачные, но без цвета, прозрачные и из цвета брать только альфа канал и пр.

Выводы:

На одном спрайте background вы не заметите прирост производительности, но сэкономленные наносекунды поднимут fps и сэкономят аккумулятор в тандеме со всеми вашими оптимизациями.

P.S. Компилированные варианты шейдеров:

compiled_variant

Все варианты скомпиленных шейдеров для дефолтного шейдера вышли на 1123 строки, а наш оптимизированный шейдер на 235 строки.

Как сшить текстуры в unity 3 d

В этом посте мы рассмотрим как можно применить подход Двигателя на Тёмной Материи для создания бесконечного 2D фона.

Если вы сталкивались с мобильными играми в общественном транспорте, то наверняка могли заметить, что одними из самых популярных в поездке являются игры жанра Endless runner, например, Subway Surfers, а для любителей археологии примером может послужить Электроника ИМ23 “Автослалом”. Основным признаком данного жанра является бесконечно перемещающийся элемента(персонаж или другой объект), который обычно самостоятельно движется вперёд навстречу препятствиям, а управление даётся только для возможности эти препятствия избегать. Бесконечное перемещение подразумевает бесконечное пространство доступное для движения игрока, создание которых является не самой простой задачей, как могло бы показаться на первый взгляд. Этим постом мы открываем цикл, в котором рассмотрим элементы, которые помогут создать такие бесконечные, в каком-то смысле, миры.

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

Проблематика

Первым что приходит в голову, когда вас просят сделать корабль, который перемещается в пространстве, это добавить модель корабля, задать ему вектор скорости, привязать к нему камеру, подложить фон и начать сдвигать корабль вдоль вектора, помноженного на Time.deltaTime . Если откинуть очевидные вещи с ограниченными размерами фона, которые в любом случае придётся решать, главной проблемой бесконечного перемещения окажется координатное пространство Unity, которое привязано к переменным типа float и с увеличением координат точность будет падать. Для более точного описания проблемы вы можете посмотреть вот это видео "64 Bit In Kerbal Space Program".

Dark Matter Engine

Для решения данного вопроса можно использовать подход, с помощью которого работает Двигатель на Тёмной Материи из “Футурамы”. Если коротко описать принцип его действия, то двигатель двигает не корабль, а пространство вокруг корабля. То есть, в нашем случае вместо того чтобы двигать вдоль вектора скорости наш корабль мы будем двигать все объекты вокруг него в противоположном направлении. Таким образом, если наша камера привязана к кораблю, то мы всегда будем оставаться в точке начала координат и наша точность не будет падать из-за увеличения расстояния. Да и в целом для решения вопроса с бесконечным перемещением, выбрать началом координат наше положение выглядит более красивым решением, нежели привязываться к какой-либо другой точке в пространстве.

Задача

Сделать перемещение космического корабля вдоль бесконечного 2D фона. Корабль можно поворачивать вокруг оси Z при помощи клика по правой/левой стороне экрана. Камера всегда будет сонаправлена с вектором движения корабля.

Решение

Я не буду распространять ассеты, которые используются для примера. Найти подходящие вам ресурсы это тоже большая работа и я предлагаю вам в этом потренироваться, если не знаете с чего начать, то можно посетить бесплатный itch.io или поискать в интернете "Free game assets" .

Читайте так же:
Thermoform термобелье размерная сетка

Нам понадобится текстура для корабля и текстура для фона. Основное требование к фону будет его зацикленность как в вертикальном, так и в горизонтальном направлении.

  1. Добавьте в проект текстуры корабля и фона, для фона необходимо выставить Mesh type — Full rect и Wrap mode — Repeat
    Add sprites
  2. Создайте структуру объектов такого содержания
    Object structure
  3. Добавьте текстуру для корабля
    Spaceship
  4. Добавьте текстуру для фона, выставите Draw mode — Tiled и Order in Layer = -1
    Add scenes
  5. Создайте скрипт UniverseHandler, добавьте его к объекту Universe
  1. Выставите в редакторе ссылки на Main camera, Ship и Space
    Univerce handler
  2. Насладитесь результатом

Результат

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

Альтернативные решения

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

Заключение

Когда мы задумываемся о создании бесконечных пространств подход Двигателя на Тёмной Материи является основным средством обхода ограничений точности для Unity. Совмещённый с обычными передвижениями сдвиг центра координат тоже можно отнести в эту же группу. Приведённый же пример прекрасно подходит для создания фонов и эффекта параллакса. Однако, работа с более сложными объектами требует иных подходов и для создания реальных неограниченных пространств необходимо ввести множество других механик. Эти вопросы мы рассмотрим в следующих статьях цикла про бесконечные миры. Пока! =)

Оптимизация 2D игр на Unity

На Youtube куча уроков по созданию простейших 2D игр на Unity. Реально, сделать неплохой платформер можно за день, при наличии опыта и готовых ассетов. Но многие начинающие игроделы сделав проект и протестировать его на ПК, с ужасом наблюдают как их творение тормозит на мобильном устройстве.

В мануалах, что встречаются в сети, большинство советов собрано к версии Unity 4.6+, кроме того, они почти все на английском, что для некоторых является преградой. В этом посте, я постарался собрать те моменты, которые помогли мне избавится от лагов на iOS и Android. Но важно понимать — не все можно решить лишь настройками, очень важна и архитектура приложения, и подготовленные текстуры, и знание более оптимальных алгоритмов.

Что нужно предпринять, чтобы повысить производительность, поднять FPS, снизить CPU?

1. Кешируем все!

Все, что будет использоваться больше одного раза лучше закешировать. Операции типа GameObject.Find() или GetComponent() достаточно ресурсозатратны, а если они вызываются где-нибудь в цикле или в Update (), то производительность может упасть.

Не используйте Resources.Load () каждый раз когда нужно в рантайме загрузить что либо, это тоже дорогая операция. Лучше при старте закешировать и работать с кешем. Ну и конечно, объединяйте в префабы.

2. Настройки графики

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

Читайте так же:
Джинсы размер 28 30 это как российский

3. Используем FrameRate

По-умолчанию FrameRate равен 30. И зачастую этого бывает достаточно. Но например, при создании UI где есть прокручивающие списки и движущие элементы, может появится дрожание или шлейф. Я это заметил при тестировании на iPhone, поэтому вручную повысил FrameRate. А понижая FrameRate на сценах или игровых меню, где ничего не двигается, можно значительно снизить CPU, а следовательно продлить жизнь батарее устройства. Пользователи не любят когда игра сжирает аккумулятор за час.

4. Атлас текстур

Определенно, нужно упаковывать все свои спрайты в атласы. Для этого есть как встроенный инструмент Sprite Packer, так и продвинутый TexturePacker. Для работы встроенного упаковщика, достаточно задавать теги в настройках импорта, объединяя текстуры и спрайты по смыслу и месту использования.

Таким образом уменьшается количество вызовов отрисовок ваших спрайтов. Проверить как идет отрисовка можно с помощью встроенного инструмента Frame Debugger.

5. Используем пул объектов

GameObject.Instantiate () — очень дорогая операция! Если есть возможность не использовать ее в процессе игры — не используйте. Для большого количества однотипных объектов надо использовать пул объектов. Один раз инициализировав определенное количество, например пуль, они будут использоваться снова и снова, вместо создания и уничтожения каждый раз. Урок по пулу объектов и готовый шаблон, для начала будет достаточно.

6. Меньше Update — больше событий

Метод Update () вызывается каждый кадр, FixedUpdate () в некоторых случаях еще чаще. Если у вас в этих местах происходит много различных проверок и действий, это можно сказаться на производительности. Я использую событийную модель: вместо проверки условия в Update (), когда происходит какое-либо действие, отправляется событие, а в нужном месте это событие «слушается» и обрабатывается в зависимости от переданных параметров. Для этого можно использовать менеджер событий о котором я писал ранее.

7. Выключаем неиспользуемые компоненты

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

8. Настройки билда

Билд под конкретную платформу, тоже можно оптимизировать. Например, если акселерометр не используется в игре, его лучше вообще отключить. Кроме того, я не использую автовыбор графического API, а задаю его сам убирая все остальные, опять же, если вы не используете какие-то специфические функции из OpenGLES 3.0, а так второй версии вполне хватает, она уже давно протестирована. Включаем статичный и динамический батчинг, а для Android многопоточный рендеринг. Для iOS включаем Script Call Optimization в Fast but no Exceptions, но тут момент — если будет какое-то исключение, то игра крашится.

9. Используем Profiler

Не стоит обделять вниманием профайлер. Обязательно протестируйте свою игру и посмотрите, в какие моменты идет максимальная нагрузка. Эти места нужно оптимизировать в первую очередь. Большинство ответов можно найти на stackoverflow.com или форуме Unity, просто загуглив название метода который тратит больше всего ресурсов.

10. Использование материала для UI Image и SpriteRenderer

Если у вас сложный интерфейс и много компонентов, особенно UI Image, то они существенно будут влиять на FPS. Чтобы повысить производительность, улучшить плавность анимаций, можно применить такой хак: там где вы не используете маски, у картинок нужно задать материал Sprites-Default. Если это сделать вместе с маской, то маска не сработает и получите примерно такой варнинг:

Material Sprites-Default doesn’t have _Stencil property

Чтобы убрать эту ошибку нужно немного изменить стандартный шейдер, сделать новый материал и применить его там где есть маска, тогда все сработает. Ссылка на измененный шейдер.
Цена плавности — повышение CPU 🙁

Читайте так же:
Как сшить юбку пачку шопенку

11. Уменьшаем размер текстур

Отличная утилита которая позволяет снизить потребления памяти для текстур до 3х раз. Как это работает и ссылка на Github, в статье на Хабре.

12. Практическое руководство по оптимизации Unity игр

Подойдет как для 2D, так и для 3D. Много полезной информации которую в документации вряд ли найдешь. Тут и про инструменты, и про опыт. Рассказывает специалист по эксплуатации из Unity Technologies — очень интересно. Узнал про memory profiler и то, что Camera.main не закеширована О_О. Обязательно смотреть всем.

13. Используем оптимизированный код

Снова хочется посоветовать набор оптимизированных скриптов от Leopotam. Коллекции, сериализация, векторы и многое другое. Настоятельное рекомендую, к изучению и использованию.

14. Используем одинаковые материалы

Если на объектах стоят разные материалы, они не будут батчится и будет больше вызовов отрисовки. Соответственно, нужно по возможности использовать как можно меньше разных шейдеров и материалов. Для понимания, как работает начальная оптимизация графики 2D, на Lynda.com есть небольшой курс.

15. Размеры атласов и спрайтов

Для применения сжатия спрайтов на мобильных устройствах нужно использовать атласы с размерами кратными степени 2, т. е. 1024х1024, 2048х2048.

16. Используйте UI Profiler

В Unity 2017 появился UI Profiler! Крутая штука, теперь можно выяснить почему в интерфейсе много вызовов отрисовки, увидеть какие материалы на объектах и всё это оптимизировать. Особенно актуально, если у вас сложные интерфейсы со множеством элементов, которые например, прокручиваются в ScrollRect.

17. Уголок оптимизатора

На сайте Unity появился специальный раздел посвященный оптимизации — Optimization corner. Там и про UI, и профайлеры, и основные ошибки, в общем, стоит ознакомиться.

18. Несколько советов по оптимизации UI

Раннее уже упоминали про Camera.main, но в новой статье описаны ещё несколько интересных особенностей оптимизации UI.

19. Сборник советов от FunCorp

Хорошая статья про оптимизацию UI. Многое уже описано тут, но есть и замечания по новым компонентам, например TextMeshPro.

20. Оптимизация UI без кода

Статья от Banzai Games про основные способы не делать неправильно Unity UI. Есть и интересные замечания. Зачем только снова про древний текстовый компоненты говорить. Думаю уже все перебрались на TMP.

21. Оптимизация мобильных 3D-проектов

Хорошая статья про оптимизацию в 3D. Многое подойдет и для 2D. Рассмотрены все аспекты и UI, и текстуры, шейдеры, батчинг и т. д.

22. Топ-10 ошибок в оптимизации Unity

Хороший вебинар от юнитеков, рассмотрены частые ошибки совершаемые при оптимизации, обзор инструментов по оптимизации, примеры с пояснениями.

23. Оптимизация игр на Unity: проверенный в деле план

Перевод отличной статьи по оптимизации игр на Unity. Как подготовиться к оптимизации, что лучше делать, что не делать, как правильно использовать профайле и многое другое.

Пока все. Тут не было про физику, потому что пока я ее не использовал. Возможно, в будущем добавлю. Пишите в комментариях ваши проверенные способы оптимизации для 2D игр под Unity.

голоса
Рейтинг статьи
Ссылка на основную публикацию
ВсеИнструменты
Adblock
detector