
Визуальный стиль моей находящейся в разработке игры 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, например, выполняет увеличение масштаба с 320x200).
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.
Комментарии (9)
yatanai
31.08.2019 21:50Я очень люблю подобный стиль, хотяб в качестве более простого метода сделать «реалистичный» пиксель арт.
Вы не знаете игр с похожем «стилем»? Никак не мог найти…Readme
01.09.2019 10:37Могу предположить, что в Dead Cells используется похожий рендеринг (ну, или анимации записывали с настоящих 3D-моделей), уж очень характерные плавные движения и «дребезг» на границе освещенностей гладких поверхностей типа штанов ГГ.
a3dline
01.09.2019 16:59а зачем создавать какойто плейн, когда можно поосто скопировать результат буфера в буфер кадра, через обычных Blit. И это не «крутая пиксельная графика» а просто рендер в пониженным разрешением. с таким же успехом можно понизить размер самого фрейм буфера через SetResolution и убрать у билинейность.
lgorSL
02.09.2019 11:34В Unity многие низкоуровневые возможности спрятаны от разработчика, там что оказывается проще создать где-то в небе камеру и перед ней прямоугольник с текстурой, чем просто взять и отрендерить текстуру на экран. Хотя для меня это всё равно дико выглядит.
AstarothAst
Раньше старались сделать графику лучше, выжимали что могли из всех этих ускорителей, а теперь наоборот — сознательно портят. Провернулось колесо сансары…
JustDont
Сам по себе вектор «графика лучше» бессмысленен. Графика нужна лучше не просто так, а для чего-то, и вектор «чего-то» со временем очень сильно менялся: сначала графику из схематичных отображений вытасктивали в приемлемую абстракцию мира (весь поход за 3D), потом улучшали абстракцию мира (дальнейший поход за мощностью видеокарт, шейдерами и т.п.), но уже тогда стало ясно, что дальнейшее увеличение полноты модели невероятно трудоёмко, и дело вовсе не в текстурах и полигонах (а в физике), и крестовый поход за полноту модели выдохся и перешел в незначимые мелочи (деревья там нарисовать, волосы, меховые текстурки, и прочую несистемную хрень).
Дальнейшая борьба за лучшую графику пока не имеет смысла за отсутствием цели. Хотя вот аппаратный raytracing в RTX — это как раз новое завоевание в сторону старой цели, вытащили кусок физики на видеокарту.