Наверняка каждый из нас слышал про NFT токены. Не буду тратить ваше время и повторять порядком надоевшие фразы, типа «NFT – это уникальный шанс войти в историю искусства навсегда», «NFT – это мыльный пузырь, и он уже лопнул», «NFT это возможность стать миллионером за секунду» и т.д.
У каждого человека свой взгляд на NFT и все они имеют место быть. Я же хочу поделиться именно приобретенным опытом с технической точки зрения. Предполагаю, что это будет серия статей по созданию коллекции. Возможно, кто-то использует полученную информацию для генерации своих коллекций, а кто-то применит отдельные знания в совершенно другой сфере.
1. Трейты
Итак, пока мы пытались продвинуть нашу NFT коллекцию VoxelCrazyHead в массы, мне довелось познакомиться и пообщаться с большим количеством других создателей. В основном это были коллекции в формате 2D изображений, но были и 3D. Меня интересовали именно генеративные коллекции, то есть те, которые создаются путем сочетания нескольких составных частей, которые могут принимать разные значения. Эти составные части называют «атрибуты» или «Traits» (Трейты).
С помощью трейтов мы создаём вариативность получаемого персонажа (картинки). Примеры трейтов из нашей коллекции:
Например, возьмем трейт «emotion». Этот трейт определяет, какая эмоция будет у головы (внимание на выражение лица):
То есть первым делом мы определились:
1) Какие будут трейты и сколько
2) Какие значения будут у трейтов и сколько
В сумме у нас получилось 12 трейтов с 324 возможными значениями, что в результате дало нам 40 778 090 496 000 возможных комбинаций голов.
После этого мы создали 3d модели трейтов: головы, шапки, цепочки, прически, очки и т.д. Можно заметить, что у кого-то есть цепочка или очки, головной убор или сережка, а у кого-то и то и другое. Именно с помощью распределения трейтов мы определяем, у кого будет тот или иной атрибут, а также насколько редким он будет. Дальше мы провели ряд визуальных тестов, чтобы понять, насколько хорошо сочетаются атрибуты, их формы и цвета. Затем приступили к распределению процентовки трейтов. На примере очков:
Общее количество NFT в коллекции – 10 000.
Трейт «glasses» распределяем следующим образом:
1) Персонажей без очков («glasses» = «None»): 7000
2) Всего очков: 3000
3) Всего моделей очков: 11
Мы распределили 3000 очков между их возможными моделями и получили, что самые редкие очки «biglineGLD» и «biglineSLV», их всего по 50 штук. Соответственно, головы с такими очками будут редкие, а значит дорогие. Количество очков модели «wayfarer» – 550 штук, значит эти очки самые дешевые:
По такому принципу распределили значения всех трейтов: эмоции, шапки, цепочки, прически, очки и т.д. После этого мы сгенерировали отдельную табличку с описанием каждой головы:
Благодаря большому количеству комбинаций трейтов, ни одной одинаковой пары NFT в коллекции нет.
На этом этапе у нас было самое главное:
1) 3d модели составляющих частей
2) общая таблица с описанием каждой головы
Осталось собирать головы и отправлять на рендер.
2.Houdini
Мы подобрались к основной части моего рассказа. Как выяснилось, многие создатели коллекций используют Blender. Но почему-то все, с кем я общался, ни разу не слышали о Houdini (даже удивительно). Сразу скажу, я никогда не работал в Blender и не могу рассуждать о его эффективности применительно к данной задаче. Но я работаю в Houdini и могу с уверенностью сказать – это отличный выбор в этом случае. Я не смогу в рамках статьи научить пользоваться Houdini, но постараюсь наглядно показать, насколько замечательный это софт и как великолепно он подходит для таких целей. Возможно, для кого-то это станет стимулом изучить эту программу.
Итак, у нас есть таблица, в которой каждая строка содержит информацию о составных частях каждой головы. Дальше отправляемся в Houdini.
Справа мы видим, как из разных частей собирается наша голова. В каждой ноде хранится своя геометрия:
У нас всего 8 нод из которых собирается вся голова, но должно быть 12 трейтов. Почему так? Потому что в ноде HEAD идет сборка по 5 атрибутам. Давайте зайдем в ноду HEAD:
Самая верхняя нода EMOTION (1) отвечает за геометрию самой головы, то есть какую эмоцию мы выбираем. Наша голова показывает язык, а значит трейт «EMOTION» = «TONGUE».
Нода EYES_COLOR (2) применяет цвет к материалу глаз
Нода SKIN_COLOR (3) применяет цвет к материалу головы
Нода TONGUE_COLOR (4) применяет цвет к материалу языка
Нода TEETH_COLOR (5) применяет цвет к материалу зубов
В конце все ноды соединяются воедино и мы получаем готовую голову. Естественно, появляется вопрос – откуда нода знает, какую выбрать эмоцию, какой цвет применить к глазам, голове, языку и зубам?
Давайте сначала разберемся, откуда вообще нода берет ту или иную геометрию головы. Естественно, мы заготовили эту геометрию заранее. Сначала мы собрали общий сетап для «вокселезации» геометрии. Он работает следующим образом – мы загружаем любую 3d модель, подключаем к нашему сетапу и через 2 секунды получаем воксельную модель
геометрии. Магия Houdini! Вот как это выглядит:
При этом у нас остается полный контроль любых параметров, например размер вокселей, а следовательно мы можем устанавливать уровень детализации:
Очень круто иметь такой контроль, потому что на разные части геометрии мы можем применять разную детализацию для достижения красивой общей картины. С помощью этого алгоритма мы заготовили всю геометрию – головы, шапки, очки и т.д. Разложили их по папкам с соответствующим неймингом.
Теперь возвращаемся к вопросу «как нода узнает из какой папки загрузить геометрию?». Вспоминаем про нашу таблицу с описанием всех голов:
Нам осталось:
1) Импортировать данные из таблицы в Houdini
2) Применить полученные данные
Первым делом переводим таблицу в CSV – формат. Затем отправляемся в Houdini, создаем волшебную ноду «csvimport» и указываем путь к таблице:
Теперь кликаем правой кнопкой по ноде и «запекаем» её (забираем данные с таблицы):
В результате нода забирает данные о всех 10 000 голов из таблицы:
Кликаем скроллом на первую точку и видим, что в ней хранятся данные о первой голове!
Что сделала нода: создала внутренние атрибуты (переменные), в которые записала полученные данные. Мы получили массив данных о всех частях голов в следующем виде:
Column_0 : Название головы
Column_1 : Описание
Column_2 : ссылка на метаданные NFT-токена
Column_3 : Номер головы
Column_4 : Дата создания
Column_5 : трейт «Emotion»
Column_6 : трейт «Skin»
Column_7 : трейт «Eyes»
Column_8 : трейт «Tongue»
Column_9 : трейт «Teeth»
Column_10 : трейт «Hair»
Column_11 : трейт «Hat»
Column_12 : трейт «BG»
Column_13 : трейт «Base»
Column_14 : трейт «Earring»
Column_15 : трейт «Glasses»
Column_16 : трейт «Chain»
Column_17 : трейт «DNA»
Теперь мы можем использовать эти переменные и собирать головы перед отправкой на рендер. Осталось только добавить переменные во все ноды и немного подкорректировать пути. Например, при сборке самой головы мы укажем в ноде «EMOTION» следующий путь:
То есть мы будем забирать данные из column_5 и в каждом кадре подставлять значение в путь загрузки геометрии. Будет получаться так:
Естественно, мы не заготавливали и не сохраняли одну и ту же геометрию, если у нее менялся только цвет. В таком случае мы просто меняли её цвет указывая нужные данные в материале.
Осталось вставить нужные переменные во всех нодах, настроить рендер и отправить на просчёт!
Мы рендерили в нашей маленькой студии на четырех машинах Ryzen 5, 32 GB, GTX 1650. Рендер Karma XPU. Весь процесс рендеринга занял примерно 7-10 дней. Получили вполне достойное качество. После рендера добавляли небольшой шумодав, но без фанатизма, чтобы не потерять детали.
Наверное, это всё, что я хотел показать. Добавлю, что Houdini очень интересный софт. С помощью него мы можем создавать любые процедурные сетапы. Например, можно взять карту какого-то района, загрузить данные и построить этот район в 3d. Это будет достаточно сложный сетап, но это реально. Мы можем забирать данные в любом виде, преобразовывать и использовать так, как нам захочется.
Если эта тема будет интересна, я продолжу написание подобных статей.
В следующей хочу рассказать, как мы генерировали и раскидывали трейты для коллекции, как собирали это в удобную таблицу. Будет немножко Python’а :-)
Спасибо за прочтение и реакцию!
#NFT #Houdini #blockchain #3d #procedural #графика #программирование #визуальное