Доброго времени суток,
Успех новой версии Unreal Engine не оставил без внимания профессионалов всех мастей. Попытки поддать, происходящую революцию, рациональному объяснению — затмило умы самых упрямых юнити-делов. Журналисты проводят сравнения со всем подряд, что только подвернётся, чтобы попытаться перевести технологии из мира идей в любое доступное пространство. Ходят слухи, что пара кодеров поступила в клинику, они лишь запинаясь, повторяли о mesh-шейдерах. А те кто видел исходники, поговаривают о необычайном цвете кода, явно, не из нашего мира, возможно тема была, даже — светлой.
Всё это безумие — породило мифы и целые культы, рей-трейсер пошёл на рей-трейсера, рей-кастера размазало между кадрами, Z-брашер, с диким смехом, скопипастил два мазка кистью по фотоскану непристойных моделей, прямо в игру, даже Чат-GPT назвала демонстрацию — deep-fake’ом, а новости — вбросом. Кроллики и драконы стали жить вместе, собаки и кошки.. а да, о чём это я..
В общем, я не могу вам сказать, чем является на самом деле этот ваш Nanite, но я могу вам сказать, чем он точно не является. И так..
Сама технология Nanite или на русском Нанит(-ов), это технология виртуальной или виртуализированной геометрии, пришедшая к нам с альфа-версией Unreal Engine 5, на данный момент доступна уже версия 5.3. Главные плюсы, которые даёт Нанит — это просто колоссальное количество отображаемой геометрии. Настолько отличающееся от обыденного, что встаёт резонный вопрос — “А что так можно было?”.
Обычные игры могут отображать до нескольких сотен тысяч полигонов(x100k), а на одну модель выходит бюджет в несколько десятков тысяч(x10k) для самых детализированных моделей.
Игры на Unreal Engine — тем временем могут отображать миллиарды(kkk) полигонов на одну модель, а топовые версии видеокарт могут в режиме отладки отображать триллион(kkkk) полигонов с частотой 60 герц. Вот схема, который что-то да доказывает:
И к всеобщей неожиданности, Нанит не потребовалось атомного реактора для запуска. Более того, отполированные версии демонстраций запускались на консолях последних версий. Не отполированные тоже, но это было потом.
Консоли — самый важный момент, так как всю историю до этого, консоли были ограничивающим фактором в разработке игр. Вы могли иметь самое мощное продвинутое железо, превосходящее всю мощь консолей в 3-5 раз на одной только видеокарте. И всё что вы могли сделать с этой мощностью — увеличить разрешение или частоту кадров, потому как максимальный уровень графики был ограничен тем, что поддерживала основа игрового движка, которая писалась под консоли.
Само слово Нанит — обозначает нано-робота, популярных в фантастике и культуре начала 2000-х, и на данный момент разрабатываемых в лабораториях. Наниты работают сообща — роем, и своим числом могут создавать огромные фигуры, причём любые, с точностью до нано-масштабов. В этом прослеживается аналогия на работу самой технологии.
С прелюдиями закончили, можно перейти к мифам.
Миф первый: Нанит — это кастомный mesh-шейдинг
Это пожалуй самый распространённый миф, и это первое, за что пытаются выдать технологию Нанитов, лица выдающие себя за экспертов в чём бы, то ни было. Миф этот породила команда несогласных Юнитишников. И секта журналистов-свидетелей гонки нового поколения.
Дело тут состоит в презентации Unreal Engine 5, презентация была настолько разгромной и восхитительной, что все конкуренты и их обслуга обнаружили себя проигравшими в гонке, о которой они даже не знали. Но о ней знали журналисты, точнее они её придумали, но они придумали её так, что это не они её придумали, а что она была реальной, а они просто были её свидетелями. Так или иначе, журналисты начали приставать ко всем с вопросами, “а что там остальные покажут?”. И тут появился новый миф, миф внутри мифа — скам-матрёшка получается. Новый миф гласил о неком ответе со стороны главным образом Юнити и всех остальных, кого только могли найти. Миф, той самой гонке.
Не то, чтобы новые версии Юнити после мая 2020 года не выходили, они выходили, но как показала история на саму гонку — ни кто не пришёл. Поэтому этот миф даже разрушать не приходится.
Однако, в потоке этих самых вопросов, журналисты сами создали череду ответов. Ответы о технологии были следующие, якобы, Нанит — это очередная итерация обычных технологий и вот-вот у конкурентов появится точно такая же технология. А Юнити сделают такой ответ.. Но каких обычных технологий? Технологий, которые показывали Nvidia на презентации в 2018 году. Ведь там были показаны лоды и отсечение геометрии. Почти как в UE5 или нет?
GDC 2018 / Nvidia / Asteroids
В 2018 году, Nvidia представила новую технологию реализованную на уровне железа, конкретно, в чипах Turing и никаких больше. Технология и называлась Mesh-шейдинг, она добавляла некие Сеточные-шейдеры вместо стандартного конвейера. В частности, заменялось всё связанное с вертексами и до растеризатора.
И это вся технология. Вообще вся. Буквально. Без нюансов. Прям, совсем вся. Если так будет понятнее — больше человечество, включая Хуанга, о mesh-шейдерах в пределах видимой вселенной не знает ничего. Вся остальная демонстрация — это уже произвольный код работающий поверх самих сеточных-шейдеров.
Сеточные-шейдеры решают конкретную проблему, известную с DirectX 3D 9, то есть с очень давнего времени. Но что касается мифа, уже на этом этапе его можно опровергнуть множеством способов:
-
Демо Asteroids можно скачать с сайта Nvidia, как и части исходного кода отвечающие за автолодинг и отсечение геометрии. С подробнейшими пояснениями и целой статьёй о том как там всё работают. С 2018 года.
-
Сеточные-шейдеры доступны любому желающему в составе DirectX 12 Ultimate и при наличии видеокарты поддерживающей их аппаратно. С 2018 года.
Как известно, ни кто ничего подобного Нанитам больше не показывал. С 2018 года. Миф разрушен.
Тем кому совсем интересно как работают, конкретно сеточные-шейдеры и почему это точно не они, продолжение.
Mesh-шейдеры и геометрия
С начала существования графического конвейера, всё было просто — есть вершины и есть пиксели, мы загружаем в видеокарту вершины и получаем пиксели. Мы можем делать что угодно с вершинами и пикселями. И всё шло хорошо, пока не появился закономерный вопрос. А, что если мы хотим — хоть как-то менять число самих вершин? Менять количество пикселей можно через вершины, но сами вершины берутся из памяти видеокарты. И половина всех технологий с тех пор введённых в DirectX 10 и 11, половина всего что различает поколения графических API — это решение проблемы динамического изменения вершин.
Первое решение это прямое чтение вершин из оперативной памяти центрального процессора. И это самый затратный способ на синхронизацию между GPU и CPU, ограничения на пропускную способность шины и памяти процессора. Попытки применить этот способ к моделям массово — дорога к слайд-шоу.
C выходом DirectX 10 появилось ещё одно прямолинейное решение — геометрический шейдер. Геометрический шейдер — это программа, которая запускается на видеокарте после вершинного шейдера. Геометрический шейдер может проводить дополнительную работу и добавлять/удалять вершины. Проблема почти была решена в DirectX 10.
Однако, на данный момент, согласно документации, любой кто использует геометрические шейдеры — совершает преступление против чести, совести, народа и бога.
Стоит углубится в работу видеокарты, чтобы осознать проблему.
Ой, не то:
И так, перед нами один из больших блоков (SMM) чипа поколения Nvidia Maxwell 2010-х годов. В одном таком SMM — 4 блока SM, именно они нас и интересуют. Оранжевым цветом отмечены Warp Scheduler, который создаёт потоки, а зелёные Core ядра — это те самые Cuda-ядра, которые и производят вычисления.
Вершинные и пиксельные шейдеры запускаются на зелёных Core-ядрах, и в данном случае, один большой блок может обрабатывать 128 вершин или пикселей разом. Но добавить поток на исполнение — может только Warp Scheduler, которых всего четыре на большой блок, и добавляет потоки он — по одному потоку за раз. Как раз тут и создаётся узкое горлышко, ведь именно на Warp Scheduler запускаются инструкции геометрического шейдера, которые добавляют вершины. После добавления вершин, над ними могут запускаться ещё и вычисления, которые могут не попадать в размер одного малого блока — 32 потока. В итоге, геометрический шейдер — это игра в “пол это лава”, где программист должен учитывать условности конкретного железа, а любое другое железо, может, вызывать неконтролируемые лаги.
Для решения проблем геометрического шейдера, который уже был под большим вопросом, с DirectX 10.1 появился — вычислительный шейдер. Вычислительный шейдер работает ещё проще — пишется программа, которая исполняется как угодно, главное, что на выходе получается массив вершин, который уже передаются в обычный конвейер.
Конечно, если бы всё было так просто, мы бы и остановились на DirectX 10.1. Вычислительные шейдеры обладают своей самой большой проблемой — они унифицированы, они запускаются на ядрах для общих вычислений и все специализированные блоки (отмечены жёлтым) видеокарты, которые намного дешевле в транзисторном бюджете, энергоэффективности и производительности — стоят без дела, пока универсальные блоки перегружены. Более того, иногда, приходится повторять поведение специализированных блоков — программным способом, что становится похоже на Уробороса производительности. Потом результат опять должен быть отправлен в стандартный конвейер, где опять пройдёт специализированные этапы. В ранних версиях видеокарт, ещё и не все блоки были доступны для вычислительных шейдеров, но это нюансы, которые со временем были исправлены.
Тесселяция — герой ситуации, который смог, но оказался никому не нужен. Она же шейдер-замощения и она решала вопрос динамической генерации геометрии, причём, через специализированные блоки, а выбор уровня детализации и итоговые трансформации — программируемые блоки, которые идеально ложатся на ядра видеокарты. Это было настолько хорошее решение с точки зрения архитектуры, что лучше придумать — сложно, даже, сейчас. Ровно настолько же это всё оказалось, большим набором недостатков на практике.
В современной графике, вся геометрия на уровне может по несколько раз вызываться для отрисовки за один кадр и даже так, обработка вершин — может занимать 10% от общей работы, остальные 90% уходят на работу пиксельных шейдеров. Тесселяция переломила ситуацию и смогла сделать обработку вершин настолько же медленной как и обработку пикселей.
Просто невероятно, но тесселяция разбивает каждый полигон(треугольник) на устанавливаемое количество от 1 до 32 частей, ну то есть, просто чтоб понятно было — на каждый полигон создается 32 полигона, каждый из которых проходит полную обработку и отсекается только на этапе растеризации. Сцена, которая весит в 32 раза больше, чем обычная, половину которой не видно. Так фиксированная функция оказалась ещё и патчем, патч применялся фиксированным для модели шаблоном.
Разработчики попытались, честно пытались сделать для моделей 3D текстуры/патчи, чтобы улучшить графику. Они честно пытались поменять саму структуру обработки сцены, чтобы хоть как-то использовать тесселяцию. Как показала история — не все модели поддаются шаблонизации. Но самый большой удар, удар, который не могла пережить ни одна видеокарта — это удар по производительности. Такой была тесселяция, которую мы знали, такой её больше нет.
И вот, 2018 год, момент, когда победитель, герой — некогда низвергнувший самые первые в индустрии принципы, геометрические шейдеры, тот кто должен был быть спасителем всех, кто обязан был быть безупречным — сам оказался в статусе “Устаревший интерфейс” / ”Не рекомендовано к использованию”.
Встречайте Mesh-шейдинг! наконец-то! Шейдер, который решил все проблемы кардинально и просто. Он полностью убирает все этапы обработки вершин классического конвейера, прямо до растеризации. В итоге, на вход подаётся массив полигонов, для каждого полигона запускается тот самый сеточный-шейдер. Уже из сеточного-шейдера можно запускать под-потоки и обрабатывать полигоны дальше как вздумается. Выходные значения будут переданы напрямую в растеризатор.
Вы правильно поняли, тот самый громогласный, разрекламированный Mesh-шейдер на деле — старый добрый вычислительный шейдер для полигонов. Эт.
int Main(Triangle Args)
Говорить, что что-либо вообще запущено на mesh-шейдерах, тоже самое как сказать “это работает на вычислительном шейдере“ / “это работает на видеокарте” / “это работает на компьютере“. Объясняет это ровно ничего.
На вычислительных шейдерах можно создать куллинг, свой, кастомный, который напишите вы используя свои алгоритмы. Как и было на презентации Nvidia, где исходный код куллинга — доступен всем.
Все связи между технологией Nanite и Mesh-шейдингом — мистификация. Nanite — это технология, сам алгоритм. Mesh-шейдер и вычислительный-шейдер — это платформа, на которой алгоритмы запускаются. Одно — другим — быть не может.
Сходство замечаете?
Теперь вы понимаете тех гениальных аналитиков, которые всё это придумали? Они же разноцветные! Значит Nanite — это mesh-шейдеры!
Последний гвоздь в крышку этого сравнения — Мешлеты (Meshlets). Мешлеты в mesh-шейдерах — это любая группа вершин обрабатываемая параллельно, это WorkGroupID. Кластеры в Nanite — это часть иерархии видимости модели, это структурная часть самой модели. Всё что связывают эти два явления — они оба показаны разноцветными, только для разметки, в реальной программе у них всех, даже, цвета нет.
Миф Второй: Наниты — это авто-LoD
Не последняя, я вас обманул. Вторым объяснением поразительного качества моделей Nanite, стал — автоматический уровень детализации. Отличительной особенностью Nanite является отсутствие LoD’ов.
Соответственно, миф гласит — Наниты, это якобы, некие скрытые ЛоДы, где вся работа с лодами скрыта от разработчика и автоматизирована движком, то есть где, то внутри Unreal Engine сам создаёт менее детализированные версии моделей и сам определяет для них расстояние, причём используется подход показа избыточной версии модели из-за чего как раз и не видно их смены.
Угадайте откуда взялось это предположение? Да — GDC 2018 / Nvidia / Asteroids.
В демонстрации показывают LoD’ing, причём обычный, не что-то похожее на LoD’ing, а именно его. Простой программный лодинг запускаемый на видеокарте, а не на процессоре:
Самый обычный ЛоДинг, даже не авто-ЛоДинг — проще некуда.
В данном случае миф больше всего форсили Юнитишники. Так как в Юнити отдельным плагином можно купить плагин авто-LoD’ing, а значит Юнити тоже так умеет. А значит и фраза, что в “Unreal Engine LoD’ов нету” — просто рекламный трюк. Сами Юнитишники пошли дальше в своих фантазиях и уже нарекли сам авто-LoD — не популярным в самом Юнити, а значит у него якобы есть какая-то там куча минусов => в Unreal Engine его тоже все будут отключать и вообще он отбирает производительность, так что это вообще минус Unreal Engine, а не плюс. Всё это вкидывалось на правах — “фантазирую что хочу”.
С выходом движка в публичный доступ, конечно же, сразу выяснилось, что ЛоДов действительно не существует ни в каком виде. И весь этот вброс Юнити-пользователей исчез так же быстро, как и появился. Но до сих пор, попадаются Юнити-филы, которые зачем-то продолжают рассказывать про авто-ЛоДы и “Юнити тоже так умеет, но не хочет”.
Наниты на само деле не имеют ничего общего с лодами, Наниты разбивают модель на кластеры точек, которые уже в свою очередь используются для куллинга. И если, считать подобное ЛоДами, то с тем же успехом можно считать любой алгоритм кулинга — лодингом. Тесселяция, тоже становится ЛоДингом, так как там тоже есть уровни детализации. И вы можете, только это теряет смысл, так как сам термин ЛоД больше ничего конкретного не значит, а становится некой абстракцией обозначающий что угодно, и применять его не будет иметь смысла. Более того, можно также применять термин Анизотропной Фильтрации, которая будет иметь даже больше общего с Нанитами. Так как кластеры разного качества используются для формирования конечной сетки, чего нет у ЛоДов.
Миф третий: Nanite — это трюк с качеством
Наиболее правдоподобный миф, который сложно раскритиковать, если не знать точно. Миф цепляется за факт того, что Нанит — это алгоритм отсечения и заявления в презентациях, которые гласят “Nanite преобразует миллиард полигонов до 5-6 млн. отображаемых в кадре” и “Nanite может отображать столько полигонов, сколько может видеть глаз”. И Юнити-пыхатели наряду с журналистами сразу же окрестили Нанит — потерей качества и чуть ли не аналогом реконструкции кадра и апскейла, за счёт чего и достигается производительность. Значит Нанит — плохой, и его будут выключать для качества.
Конечно и это не так, Нанит имеет настройку по уровню качества. И при 100% качестве, Нанит отображает геометрию в эталонном качестве. То есть изображение построенное Нанитами — пиксель в пиксель равняется изображению нарисованному классическим конвейером.
Уловка тут присутствует, но эта уловка принадлежит классическим API. Которые и так отбрасывают полигоны при сэмплировании. В классическом конвейере существует — Sample Point, это точка сэмплирования для каждого пикселя, которую должен пересекать полигон, обычно это центр пикселя. Если полигон её пересекает, то он отправляется в растеризатор, а если нет, то просто отбрасывается.
То есть если представить что в один пиксель помещается множество полигонов модели, то из всех них, отобразится только один, который пересекает центр, сколько бы изначально не попадало в пиксель, ни миллион и не миллиард, а ровно один. Даже если если несколько полигонов пересекаются ровно в центре, существует отдельное правило, обычно это правило приоритета по часовой стрелки, которое говорит какой один единственный полигон будет отображён.
Миф четвёртый: Наниты — это очередная итерация технологий, скоро у всех так будет.
В первом абзаце, я уже касался этого момента, так и общей нитью через всю статью идёт этот посыл. Как я отмечал, на гонку ни кто не пришёл. Хотя, до сих пор журналисты, в надежде, постоянно пророчат, что выйдет новая версия какого-нибудь, обычно очень конкретного движка, которая станет не хуже, а то и лучше этого вашего Unreal Engine. В ход идёт всё подряд, попытки выдать фотограмметрию и 3D сканы за “такое же как в Анриале”, попытки говорить, что остальные тоже показывают хорошую и красивую графику. И сложно с ними не согласиться, однако, отрыв Анриал — просто колоссален, и существует пропасть между хорошей и потрясающей графикой.
Как я уже замечал, все предрекаемые в будущем технологии, существовали задолго до выхода Нанитов. Юнити очень продвинутый игровой движок, в последних версиях, которого доступен, чуть ли не полностью, кастомный рендер. Любой желающий может подключить как Mesh-шейдеры, так и любую другую технологию к Юнити.
Ни кто за всё это время не сделал ничего подобного Нанитам. Нанит — это полностью новая, отдельная технология, созданная с нуля. Разработанная целыми отделами R&D. И ни кто даже заявок не делал на реализацию, хоть чего-то революционного, а говорить об конкуренте Нанитам — не приходится вовсе. Все остальные делают очередную итерацию, Unreal Engine 5 — выкатил революцию.
Малые мифы
Дальнейшая “критика” в адрес Анриала, это эксплуатация его ограничений, которые обычно выражаются “ну анриал — это не серебряная пуля”. Однако, несложно заметить, что серебряных пуль не существует вовсе. Более того, универсальность технологий обычно идёт в ущерб производительности. И тут только вам делать выбор.
Технология Нанит, действительно, накладывает множество ограничений, но Unreal Engine 5 находится на стадии разработки и развивается постоянно. Так к примеру до последнего времени, на сетки с Нанит было нельзя накладывать кастомные атрибуты, что накладывало просто огромные ограничения, а потом с версией 5.2 их просто добавили в полной мере и теперь Нанит можно применять к растительности.
Всвязи с этим у журналистов сложился очень крепкий миф о высокой прожорливости Unreal Engine 5. И это вообще не так. Новые технологии опциональны. На голом Анриал 5, игра перенесённая с Анриала 4 — будет работать быстрее. Нанит — это тоже технология снижающая потребление ресурсов, она может выдавать не только модели высокого качества, но и огромное количество самих моделей, включение технологии Нанит для проекта на Анриал 5 — увеличит производительность. Прожорливыми технологиями, являются, только технологии глобального освещения — рейтрейсинг и его более быстрый аналог Lumen.
Образы будущего
Немного о том, что нас ждёт. Во-первых, Нанит не присутствует на мобильных устройствах. Для работы Нанит требуется поддержка виртуальных ресурсов, они же тайловые ресурсы, которые существуют в DirectX с версией 11.2 и из видеокарт поддерживается начиная с поколения Nvidia Maxwell 2 (900-серия). Последние версии мобильных устройств и VR, поддерживают их, и выход Нанит на мобильные устройства — просто вопрос времени.
Unreal Engine развивается дикими темпами, подминая рынок под себя. На данный момент почти все новости и события, указывают, что доминирование Unreal Engine только растёт. Теперь, даже, крупные студии переходят со своих самописных движков на Unreal Engine, и более того, Unreal Engine всегда был наиболее похож на кастомные движки крупных компаний. Поэтому, если перед вами вдруг стоит вопрос выбора технологий на будущее, не важно при этом обучаетесь вы или выбираете двигло для себя — вам определённо стоит сделать выбор в пользу Unreal Engine, хотя бы в тестовых проектах, чтобы не обнаружить себя в подвешенном состоянии, когда тот или иной движок неожиданно утонет.
Конкуренты, не выпустят аналогов примерно — никогда. Самый главный из них Unity — всегда занимал абсолютно другую нишу. Все его странности обусловлены тем, что Unity — это компания живущая в кредит, даже в свои самые популярные годы они были убыточной компанией. Это абсолютно нормальная практика, и Unity никогда не был про графические технологии. Более того, попытка выйти на этот рынок — форменный шаг с обрыва. Им только предстоит начать зарабатывать в своей ниши, и никаких огромных отделов R&D для экспансии у них не может быть, даже если бы они очень хотели. У Юнити всё ещё крепкая бизнес модель они покупают рекламные компании, а не технологические. Чтобы им конкурировать с Анриалом им нужно не быть Юнити вовсе. На данный момент в пределах 1-1,5 лет, Юнити будет оставаться в своей ниши. Но именно развитие Анриала и тот самый возможный выход последних технологий на мобилки — это первый звоночек о том как всё может кончится, о чём говорят движения самой компании.