Русский
Русский
English
Статистика
Реклама

Generative art

Перевод Визуализация списка женщин-лауреатов Нобелевской премии в виде кристаллов в 3d с использованием Vue, WebGL, three.js

13.06.2020 22:23:27 | Автор: admin
image

Год 1 | вдохновение


В этом месяце я очень долго пыталась определиться с датасетом и идеей для его обработки. Хотя я начала думать о нем еще в мае, по факту законить удалось только через 8 месяцев (черт, я плоха), а описать проект мне удалось еще спустя месяц (оу, я чертовски плоха).

Идея проекта пришла ко мне после просмотра фильма Безумно богатые азиаты. Мне очень понравилась актриса Мишель Йео, но идея оформилась только после того, как я прочитала больше о ней и узнала, насколько она была выдающейся и крутой. Это заставило меня задуматься выдающихся женщинах, о которых я понятия не имею. И вот возникла идея как-то это визуализировать.


1 неделя | данные


После формирования концепции, возник следующий вопрос как собрать необходимые данные? Я быстро пришла к идее использовать Википедию, попытаться спарсить лучших женщин оттуда. Я понятия не имела, как определить лучших (просмотры страницы? длина страницы? ссылки на страницу?). Хотя я посмотрела статью на The Pudding про визуализацию на основе данных википедии, я все еще не была уверена, что хочу двигаться в эту сторону. А еще мне очень не хватало свободного времени.

Затем мне пришло в голову, что, возможно, я должна использовать фиксированный список женщин, и это каким-то образом привело меня на страницу 51 женщин-лауреатов нобелевской премии. Я не слышала о большинстве из них, и мне захотелось узнать больше. Для проекта это подходило идеально.

image

С этого момента я начала изучать разные методы использования API Википедии. Разобраться было непросто (я не была уверена, нужно ли мне использовать Wikidata или MediaWiki, это те варианты, которые возникали при поиске Wikipedia API в Google), но, к счастью, уже упомянутая выше статья на Pudding помогла мне закрыть эти вопросы. Быстрый просмотр их репозитория wiki-billboard-data привел меня к выбору одного из скриптов с wikijs, и я могла просто воспользоваться этим пакетом.

Все, что мне нужно было сделать, это скопировать и вставить список знатных женщин-лауреатов в электронную таблицу и выполнить небольшое форматирование/чистку.

Один из самых важных уроков, которые я узнала о сборе данных электронные таблицы отлично подходят для их очистки. Раньше я пыталась писать код для очистки данных, и это занимало у меня намного больше времени. Когда я собирала данные для проекта по Гамильтону, я буквально набирала запятые между каждой ячейкой в строке в моем CSV настолько я была глупа.


Затем я экспортировала электронную таблицу как CSV, потом использовала онлайн-конвертер, чтобы получить данные в формате JSON.

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

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

неделя 2 | скетч


Не буду врать, я так долго думала об этом проекте, что даже не могу вспомнить все идеи, которые у меня возникали в процессе. Все, что я помню, это то, что я просматривала номинантов премии Information is Beautiful, когда решила, что мне нужно как-то выделить те записи, которые мне действительно нравятся в моих сохранениях. Это заставило меня осознать, что я должна лучше организовать свою доску на Pinterest, так как раньше я сваливала все мои идеи и видение на одну доску. В процессе чистки, я наткнулась на эту великолепную картину с кристаллами художника Ребекки Шаперон, которую я сохранила на будущее несколько лет назад. Почти сразу я поняла, что я хочу программно воссоздать их. Ведь было бы прекрасно визуализировать этих выдающихся женщин в качестве ярких разноцветных кристаллов?

image

Возможно, у меня были другие идеи до этого момента (да, очень возможно), но я не могу их вспомнить идея с кристаллами подходила идеально.

После этого я продумала другие детали: размер кристаллов должен отражать влияние женщины количество ссылок на ее страницу в Википедии. Число граней на кристалле будет сопоставлено с количеством источников в нижней части ее страницы (поскольку она многогранна), а цвет будет определяться категорией премии. Единственное, что мне пока было непонятно, это как расположить кристаллы. Я долго думала, что мне надо просто выложить их в 2-х измерениях по x / y и заставить читателя прокручивать их.

А потом я приняла участие в семинаре Мэтта ДесЛориерса по креативному кодингу, где он преподавал canvas, three.js и WebGL. Семинар открыл мне концепт третьего измерения, и я сразу поняла, что собираюсь использовать год получения награды в качестве оси z. Далее один мой друг предложил сделать потоки-нити, связывающие тех, кто сотрудничал друг с другом таким образом, чтобы их положение тоже менялось в зависимости от этого (но в итоге у меня не было времени на реализацию этой идеи).

Вся концепция пришла ко мне так быстро и естественно, что я не сделала ни одного наброска в процессе. Я просмотрела свой блокнот, но там вообще ничего нет.

неделя 3 & 4 | кодинг


Это был отличный месяц для кодинга.

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

И вот однажды меня осенило (я не уверена, что послужило причиной), что я не умею думать в трехмерном физическом пространстве, как раз потому, что я постоянно работаю в плоском диджитальном формате. Если бы я смогла научиться работать с 3D в цифре, то смогла бы мыслить в объеме и в физическом мире. Я добавила three.js и WebGL вверх своего списка для изучения.

В конце октября я прошла семинар Мэтта по креативному кодингу и изучила основы three.js, введение в фрагментированные и вершинные шейдеры. Я выучила правило буравчика: используйте большой палец для оси X (увеличивается вправо), указательный палец для оси Y (увеличивается вверх, что противоположно SVG и canvas) и средний палец для оси Z (для увеличения экрана и приближения его). Я узнала, что WebGL работает не в пикселях, а в единицах (похожая ассоциация футы или метры).

Затем в ноябре я вписалась в один конкурс по WebGL. Хотя я раньше не имела с ним дела, я надеялась, что дедлайн даст мне мотивацию, необходимую для завершения проекта. Я начала 1-го декабря и поставила себе цель делать чуть-чуть каждый будний день, пока не смогу дойти до чего-то презентабельного 23-го декабря (финал конкурса).

Сперва я прочла первые две главы Руководства по программированию на WebGL, в котором рассказывалось, как настроить WebGL. Затем я повторила свои знания по three.js. После я запустила блокнот из Observable, чтобы понять минимально-необходимые настройки для рисования чего-либо в three.js (рендерер, камера и сцена, а затем вызвать renderer.render(scene, camera) для отображения ). Мне всегда нравилось понимать самые основы работы кода, так что это было очень полезно.

После настройки я решила создать форму кристалла. Я использовала PolyhedronGeometry, потому что так я могла просто определить набор вершин, а затем указать вершины, которые будут составлять треугольную грань. В первый день мне удалось создать только один треугольник.

image

А во второй день кристалл (на который потребовалось две попытки, потому что в первый раз я налажала с математикой).

image

А потом, в конце концов, форма кристалла, который был у меня в голове.

image

Позже я поняла, что есть лучшие способы делать то, что я хотела (и на самом деле PolyhedronGeometry это довольно утомительный способ делать это), но я была очень рада возможности попрактиковаться в координатах x / y / z в WebGL.

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

image

Следующей задачей стало научиться использовать фрагментный шейдер для окрашивания кристалла. Здесь мне пришлось немного отклониться от плана, потому что я не могла понять, как использовать glslify (узловая модульная система для GLSL, на которой написаны шейдеры, которые я взяла в качестве образца). Вместо этого я начала изучать различные инструменты компоновки/сборки, чтобы в конечном итоге развернуть свой код в Интернете. В конце концов, я решила использовать Parcel (вместо Vue CLI, который я регулярно использую последние полгода), потому что он имеет встроенную поддержку как Vue, так и GLSL.

Вот такой кристалл с наложением того же паттерна шума у меня получился.

image

Результат мне не нравился, поэтому я решила, что мне нужно больше узнать о шейдерах и использовании цветов в шейдерах. Именно в этот момент я обратилась к Books of Shaders Патрисио Гонсалеса Виво и, в частности, к главе Shaping Functions. Я узнала о синусах, косинусах, полиномах и экспонентах функциях, которые могут брать число (или набор чисел) и выводить на их основе другие. Я также узнала о смешивании цветов и о том, как мы можем взять два цвета, и не только получить новый цвет посередине между этими двумя, но также смешивать цвета в формате RGB и создавать совершенно новые на их основе. Если мы объединим это с функциями формы, то сможем получить градиенты и формы:

image
Эти были получены путем смешивания синего и желтого, а также изменения значений RGB в каждой позиции с помощью степеней, синусов, абсолютных значений, шагов и сглаживаний

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

image

Но результат мне не понравился по двум причинам:
  • Я жестко задавала формы каждой фигуры, поэтому у меня было только три разных фигуры: прямоугольник, прямоугольник с треугольником сверху и прямоугольник с треугольником сверху и снизу. Это означало, что большинство кристаллов были просто прямоугольниками.
  • Я также хотела, чтобы цвет для каждой категории выбирался из шести базовых цветов, поэтому для каждого кристалла я использовала только один цвет. Цвета мне совсем не нравились.


Примерно в это же время я наткнулась на демо Bloom (эффект постобработки для создания свечения), и в нем были круглые, похожие на драгоценные камни объекты, которые выглядели довольно похоже на кристаллы, которые я и хотела получить:

image

Я посмотрела исходный код и поняла, что они использовали SphereGeometry, но с включенным flatShading поэтому вместо рендеринга гладкой поверхности он показывал каждую отдельную грань. Я осознала, что, как я могу манипулировать и смешивать цвета, чтобы получить новые цвета, совершенно отличные от оригинала, так же я могу фактически управлять геометрическими параметрами (например, количеством граней) и получать новую геометрию, которая выглядит аналогично, но отличается от исходной.

Поэтому я заменила PolyhedronGeometry на SphereGeometry, установила высоту на 4 и ширину на свои данные, растянула фигуру, установив вертикальный масштаб в два раза больше по горизонтали, добавила jitter (дрожание) для каждой вершины, и у меня получились гораздо более интересные формы:

image

Теперь, когда я определилась с формами, настало время вернуться к цвету. На этот раз я использовала два цвета и смешивала их с функциями формы:

image
image
Мне нравится первый вариант выглядит как картофель

Поскольку шейдер по умолчанию просто обтекает фигуру (по крайней мере, так мне нравится думать об этом), я потеряла четкие края. К счастью, меня научили возвращать формы обратно, вызывая computeFlatVertexNormals() на геометрию, получая нормали в вершинном шейдере и передавая его фрагментному шейдеру при этом добавляя его в цвет. Это не только сделало края четко очерченными, но также дало иллюзию света и тени:

image
Код для добавления нормалей сторон.

После этого я поигралась с двумя наборами градиентов: один для гуманитарных наук (мир, литература, экономические науки), а другой для естественных наук (физика, химия, медицина).

image

Затем занялась фоном. Я создала пол с помощью PlaneGeometry и случайного дрожания y-позиции каждой вершины (вдохновленной этой статьей из codrops), а также небо, создав огромную сферу вокруг сцены. Я экспериментировала с тремя различными типами источников света: полусферой, рассеянным (чтобы создать длянеба ощущение заката/восхода солнца), и направленным (чтобы отбрасывать тени от кристаллов на пол).

image

В конце я добавила звездочки, которые визуализируют всех мужчин, которые выиграли премию за тот же период времени, а также аннотации для каждого кристалла и для десятилетий. Это было сложно, потому что с тем текстом, который у меня был, использовать TextGeometry было практически бесполезно. Решение, которое я нашла после поиска в интернете, визуализировать текст в HTML5 Canvas, создать PlaneGeometry и использовать этот Canvas в качестве текстуры для заполнения PlaneGeometry. Очень интересный подход.

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

image

Вот ссылка на финальный результат на GitHub

И видео c демонстрацией результата:



Если вы хотите попробовать еще что-то или начать с более простых проектов:

Подробнее..

Перевод Чему я научился за (почти) 30 дней Codevemberа 30 скетчей на p5.js

15.06.2020 20:17:21 | Автор: admin
image

Что такое #codevember и зачем он нужен? В последние пару лет каждый ноябрь я натыкался в соцсетях на интересные произведения искусства, созданные ИИ, отмеченные этим хэштегом. Согласно информации с codevember.xyz:

Codevember это челлендж для разработчиков, созданный для того, чтобы отточить их креативность и улучшить навыки. Цель каждый день ноября создавать креативный фрагмент кода. Мы будем давать вам рекомендации для вдохновения каждый день, но вы можете создавать свои скетчи.

В этом году я решил попробовать поучаствовать и в ноябре изучить Processing (p5.js) и побаловаться созданием графики, которая создана не для какой-то определённой задачи.



Подготовительной работой лучше заниматься в фоновом режиме



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

Я раньше читал Природу кода Дэниэла Шиффмана. Он начинал с броуновского движения и текучих форм, которые, как я думал, могли быть использованы в точке размещения пера для рисования.

image

image
Стандартное случайное блуждание, и затем использование координат для рисования линий и кругов

Темп важен



Соблюдение постоянного темпа позволило мне не забыть синтаксис и размышлять, совершенствуя скетчи в течение нескольких дней, а не начинать с нуля каждый раз. Хоть иногда это казалось жульничеством, порой результаты меня радовали.

image
image
image
image
Использование текучих форм как инструмента для рисования

Легко впишется в твой день, но не в каждый


Я был довольно-таки постоянным, но несколько дней я пропустил и наверстал на следующий день, сделав два скетча. Был и день, который я не наверстал. Имея семью и работу с полным рабочим днём, втиснуть новую привычку, которая может занять до 30 минут, не всегда возможно.
image
image
Цвет волны на картине Хокусая отбирается и перерисовывается в виде рисунка брызгами и проецируется в случайные 3D плитки, отсортированные по осветлённости

Ежедневные скетчи не лучший способ изучения нового языка


Учитывая мои ограничения по времени и способности вникнуть, большая часть обучения языку Processing прошла в спешке. Я много изучал примеры, чтобы разобраться в возможностях p5.js и часто брал и адаптировал чужой код, чтобы заставить всё работать. Всё это работало, но у меня не было особо времени выучить всё до автоматизма.

image
Перисто

Я отдаю предпочтение одной цветовой гамме


Что мне нравилось в работе с цветами в p5, так это цветовое пространство HSB (тон насыщенность яркость). Оно куда более интуитивно понятно, чем RGB (кто-то вообще задумывается о том, сколько красного, зелёного и синего в цвете?) или HEX. Несмотря на доступ к новым методам кодирования цветов, меня постоянно тянуло назад к моим обычным цветовым привычкам. Не то что бы это было плохо, просто вещь, которую я для себя осознал.

image
Обычно это тёмный фон, узкий диапазон приглушённых цветов, иногда использование режима наложения Dodge

(И теперь я понимаю, что годами упускал из виду цветовые режимы HSB/HSL в d3.js)

Комплексные системы золотая середина


Несколько дней спустя я нашёл онлайн курс, который называется Generative Art and Computational Creativity from Philippe Pasquier, который до сих пор прохожу. История ИИ искусства куда глубже и шире, чем я мог себе представить, и есть формализованная систематика, что хорошо. Эта диаграмма форм поведения ИИ систем как раз донесла до меня, что я искал и почему мне порой нужно столько времени, чтобы решить, что скетч готов.

image

Фиксированные системы (fixed) формируют единственный статический вывод; периодические системы (periodic) колеблются между двумя или более состояниями; хаотичные системы (chaotic) не формируют никакого предсказуемого образа (я думаю, не считая вещей, типа странных аттракторов), но комплексные системы (complex) дают нам структуру и стабильность периодических систем и координированную рандомность хаотичных систем.

image

Неправильное использование тоже стратегия



Порой я застревал на некоторых моментах, пытаясь создать что-то в 3D. И чисто возясь с кодом я создавал, в конце концов, что-то далёкое от того, что я пытался сделать, но достаточно интересное, чтобы назвать это скетчем. Вместо того чтобы передвигать 3D фигуру во времени, я рисовал поверх ещё одну слегка изменённую фигуру, и получалась многослойная фигура.
image
image
image
Ошибки сделаны

Я вдохновляюсь комплексными полароидами Дэвида Хокни: художник берёт камеру-полароид, и вместо создания обычного снимка, делает снимок с ломанным эффектом глаза стрекозы и без фиксации в одной временной точке, который невозможно было бы сделать без использования этой технологии неправильно.

image
David Hockney, The Scrabble Game, 1983

Я прорываюсь к координированному разрушению красивой математики



Совершенные формы хороши, но оторваны от жизни. Интрига кроется в изъянах: что пошло не так с этим прекрасным планом действий?

Изображая и создавая системы, содержащие в себе одновременно структуру и правила вместе с шумом и рандомом, я работаю больше над раскрытием красоты в неожиданных проявлениях.

image

Забавно наблюдать за тем, как эти скетчи рисуют сами себя.

Посмотреть всю коллекцию можно на гитхабе.

Если вы хотите попробовать еще что-то или начать с более простых проектов:

Подробнее..

Перевод Визуализация изменения климата при помощи интерактивного генеративного искусства

28.10.2020 14:12:50 | Автор: admin

Чтобы мотивировать людей активнее бороться с изменением климата необходимо постоянно искать новые креативные способы. Их много: начиная от привлечения внимания к через крупные мероприятия, вродеDavos 2020, вплоть до визуализации последствий глобального потепления при помощи современных технологий обработки данныхи интерактивного генеративного искусства.

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

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

Интерактивное генеративное искусство - едва заметное, но влиятельное

Все знакомы с сайтами прогноза погоды, которые используют иконки климатических явлений, просто и удобно передающие нынешнюю или будущую погоду. Однако, иконки не могут передать динамические свойства погоды, вроде ветра.

И поэтому мы подумали о создании живого окна, которое показывает погоду и её изменение. Мы решили создать веб-приложение, которое будет показывать нынешние погодные условия, используя природный ландшафт, созданный путём вычислений, но в то же время с внутренней эстетикой. Другими словами, при помощи генеративного искусства.

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

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

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

К тому же этот подход обращает дополнительное внимание на насущный вопрос вырубки лесов. Можно легко увидеть, как долго растет дерево. Показ этих данных таким уникальным способом вызывает ощущение безотлагательности и необходимости действий. Этого тяжелее добиться сухими цифрами и статистикой.

Для реализации этого проекта использовался JavaScript, визуальные элементы нарисованы при помощи Canvas. Ландшафт состоит из четырёх главных компонентов: дерево, земля, небо и осадки. Этого достаточно, чтоб показать времена года и основные погодные условия.

Дерево

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

Нужно сгенерировать массив веток, или точнее - массив качеств веток. У каждой ветки должен быть свой угол наклона по отношению к ветке-родителю, своя длина и цвет, наклон листьев. Длина и угол наклона веток выбирается случайно согласно глубине дерева. Однако, нужно добавить или вычесть угол ветки-родителя. Так мы получаем две ветки, торчащие в разных направлениях.

Крона дерева не однородна, как, например, сфера, а состоит как бы из групп сфер. В результате цвета листьев разные, ибо некоторые из них темнее, а некоторые светлее. Поэтому крона поделена на две части, а каждая группа прокрашена слева направо плавной палитрой, переходящей от самых ярких к самым тёмным цветам. Функция divide(start,finish,intervalsAmount,n) делит числовой интервал между startиfinish на сумму интервалаintervalsAmount, и определяет интервал, включающий n.

const branchGroupDepth = 10; const leavesGroupSize = 2 ** (branchGroupDepth-1); let groupCounter = 0; function generate(angle, depth, arr) { let leafColor = colors[divide(0, leavesGroupSize, colors.length, groupCounter)]; arr.push({ angle, branchArmLength: random(minBranchLenght, maxBranchLenght), color: leafColor }); if (depth === branchGroupDepth) { groupCounter = 0; } if (depth === 0) { groupCounter++; } if (depth != 0) { if (depth > 1) { generate(angle - random(minAngle, maxAngle), depth - 1, arr); generate(angle + random(minAngle, maxAngle), depth - 1, arr); } else { generate(angle, depth - 1, arr); }}}

Задача функции branch() - заставить деревья выглядеть живыми, она высчитывает координаты веток каждый раз, когда ветер меняется. Каждая ветка двигается по круговой траектории, где начало ветки обозначено центром круга, а длина - радиусом. Единственное, что нам нужно найти - координаты конца ветки (которые ещё и являются началом следующих веток).

windSidewayForce - направление движения ветки по направлению ветра.

bendabilityOfCurrentBranch - коэффициент наклона ветки по ветру, зависящий от толщины ветки (или глубины дерева).

calcX(angle, r)/calcY(angle, r) функции, которые вычисляют координаты концов веток при помощи формулыrcos(angle)/rsin(angle).

let branchCounter = 0; const bendability = 2; const leafBendability = 17; function branch(x1, y1, arr, depth, windConfig) { if (depth != 0) { const xx = calcX(dir, depth * branchArmLength); const yy = calcY(dir, depth * branchArmLength); const windSidewayForce = windX * yy - windY * xx; const bendabiityOfCurrentBranch = (1 - (depth * 0.7) / (maxDepth * 0.7)) ** bendability; dir = angle + wind * bendabiityOfCurrentBranch * windSidewayForce; let x2 = x1 + calcX(dir, depth * branchArmLength); let y2 = y1 + calcY(dir, depth * branchArmLength); lines[depth].ush([x1, y1, x2, y2]); if (depth > 1) { branch(x2, y2, arr, depth - 1, windConfig); branch(x2, y2, arr, depth - 1, windConfig); } else { branch(x2, y2, arr, depth - 1, windConfig); } } else { const leafAngle = angle + wind * windSidewayForce * leafBendability; leaves[color].push([x1, y1, leafAngle]); } }

Ветки дерева прокрашиваются простойlineTo()канвас функцией, и каждая ветка - линия. Листья красятся двумя кривыми Безье при помощи функции bezierCurveTo(). Кривые Безье состоят из трёх точек: начало (синяя), конец (синяя) и контроль (жёлтая). Последняя придаёт кривой форму.

Покраска листьев кривыми БезьеПокраска листьев кривыми Безье

Однако, у канвас функций есть определённая особенность: нельзя красить несколько фигур несколькими цветами или несколькими движениями одновременно. Поэтому все ветки сгруппированы по толщине, а все листья - по цвету. Чтобы ускорить рендеринг, их красят группами. Также холсты деревьев хранятся под ключом (индикатором ветра), чтобы увеличить скорость рендеринга. Это означает, что программе не нужно каждый раз вычислять с начала каждое дерево, используя один индикатор ветра.

Земля

Земля (или, скорее, трава) не менее важна, чем дерево, ибо трава может показывать ветер и времена года. Нужен массив столбцов, чтобы сгенерировать траву. Каждый столбец травы должен иметь свои координаты, обозначающие положение в поле, скорость реакции на ветер и угол наклона по отношению к земле. Более близкие столбцы травы должны иметь более насыщенный и контрастный цвет, а дальние должны казаться более сглаженными. Эта визуальная хитрость даёт ощущение травяного поля. Поле поделено на горизонтальные части, у каждой части свой цвет столбцов. После генерации массива поле нужно отсортировать от самых дальних до близких по y координате для эффекта наложения друг на друга.

function generate(number) { for (var i = 0; i < number; i++) { var y = random(fieldTopStart, h + fieldBottomDeviation); var x = random(0, w); var colorGroup = divide(fieldTopStart, h + fieldBottomDeviation + 1, fieldAreas, y); var color = colors[colorGroup][random(0, colors[colorGroup].length)]; var angle = random(-maxAngleDeviation, maxAngleDeviation); var speed = random(minSpeed, maxSpeed); dots.push([x, y, color, angle, speed]); } dots.sort()}

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

Столбец травы красится двумя кривыми БезьеСтолбец травы красится двумя кривыми Безье

Небо и осадки

Облака и количество облаков - самые главные характеристики неба. Облака должны различаться по размеру относительно положения в небе. Поэтому небо поделено на горизонтальные части: в более высоких частях находятся большие облака, двигающиеся быстрее.

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

Ещё один важный элемент неба - это осадки: снег и дождь. Капли дождя красятся простой вертикальной линией, а их толщина зависит от силы дождя. Снежинки красятся градиентым полупрозрачным кругом. У каждой снежинки свой размер, и чем больше она, тем быстрее падает. Это создаёт эффект, будто большие снежинки находятся ближе к экрану.

Как выглядит генеративное искусство, основанное на погоде?

После некоторых манипуляций, включающих использование разных цветов для разных времён года и интеграцию с живыми данными, мы можем показать через живое окно весь год.

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

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

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

Популярные посты по генеративному искусству:

Подробнее..

Перевод Как заставить генеративные изображения выглядеть естественно при помощи математических алгоритмов

16.06.2020 18:07:02 | Автор: admin
image

Время от времени мне пишут комментарии о том, что мои работы не выглядят созданными компьютером. Как по мне, это лучшая похвала: мой глубокий интерес к генеративному искусству начался, когда я осознал его способность создавать как раз такие работы. Здесь я расскажу некоторые методы, которые я использую для улучшения естественности своих работ.

Этот пост не о языке и не о фреймворке. Мы будем говорить только о технике.

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



Ведущий принцип: моделируйте свои работы на основе реальности



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

Например, равномерно распределённые данные обычно не встречаются в природе. Большая часть данных представляет из себя что-то вроде колоколообразной кривой. Использование нормально распределённых случайных величин (те, что со средним значением и стандартным отклонением) чаще всего создаёт более естественный эффект, чем случайный выбор из промежутка или списка.

Линии


Предположим, что у нас есть тип данных, представляющий из себя отрезок. Чтобы нарисовать его, обычно мы делаем как-то так:

1. Выбрать начальную точку
2. Выбрать конечную точку
3. Провести черту между точками

В результате получается что-то такое:

image

По-моему, слишком идеально!

Случайный наклон



Предположим, что мы рисуем несколько горизонтальных линий, и мы хотим их сделать более естественными. Сперва можно немного подвинуть конечные точки линий. Мы можем сделать это, переместив их, используя нормальное распределение с небольшим стандартным отклонением в х и у направлениях.

image

Волнообразное колебание



Теперь у нас линии, которые немного смещены от изначально заданной позиции. И немного различаются по длине. Однако, они совершенно прямые. Это не похоже на линии, которые мы встречаем в реальном мире. Давайте сделаем их менее прямыми.

Например, это можно сделать так:

1. Выбрать N точек между конечными точками отрезка, чтоб создать новую линию.
2. Сместить каждую точку.
3. Смягчить линию и нарисовать её.

Есть много вариаций этого паттерна. Простая взять N интерполированных точек между начальной и конечной точками, поправить каждую из них с помощью статического стандартного отклонения, как делали раньше. Я буду использовать алгоритм изменения кривой Чайкина, чтоб получить сглаженную прямую. Вот так выглядит результат:

image

Влияние соседних точек



Хорошо, у нас начало что-то получаться. Изменение параметров стандартного отклонения позволяет нам контролировать колебания нашей линии. Однако, вы, наверное, заметили, что колебания независимы друг от друга. Линия может колебаться, то приближаясь к соседней верхней, то к нижней линиям. Чтобы уберечься от этого, я предлагаю такой вариант.

Возьмите среднее значение каждой пары смежных точек в вашей полученной линии после корректировки (это очень простой пример ядерного сглаживания). Вы можете сделать его несколько раз, чтобы получить более плавную линию. Нарисуйте теперь через точки кривую. Теперь каждая точка влияет на соседнюю более естественно.

image

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

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

Текстурирование линий



Теперь наша линия выглдяит достаточно естественно. Но мы всё ещё рисуем идеально точной ручкой, когда мы вызываем функцию stroke(). В реальном мире, когда мы используем различные инструменты для рисования, у них есть различия в текстуре. Один из способов внести эти различия использовать технику песчаных сплайнов, популяризованную Андерсом Хоффом (a.k.a inconvergent). Идея проста:

1. Совсем чуть-чуть скорректируйте каждую точку линии, используя нормальное распределение.
2. Сгенерируйте ещё несколько точек, между каждой соседней парой точек, и нарисуйте их в виде крошечных точечек.
3. Повторите несколько раз.

Если ваши точки супер маленькие, то получится такая текстура:

image

Это только один из множества способов придания текстурности линиям, но также это моя любимая тема для начала. Экспериментируйте со своими текстурами и увидите, что лучше подходит для вас.

image
Сон о пустыне (2018) Текстурированные линии основа многих моих работ.

Формы



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

Мы можем просто нарисовать квадрат.

image

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

image

Можно выбрать и сгладить точки между каждой соседней координатой, чтобы получить кривой квадрат.

image

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

image

Ничего из этого не ново. Мы здесь, по сути, говорим только о замкнутых отрезках, поскольку мы просто сглаживаем углы. А что насчёт заполнения пространства? Мы можем использовать функцию fill(), но это немного скучно.

image

Чтобы сделать текстуру поинтереснее, можно заполнить четырёхугольник штриховыми элементами, сгенерировав множество точек внутри него*. Мы упростим фигуру снова, чтобы сделать границы более понятными (можно штриховать и сложные фигуры, но давайте пока по-простому).

image

* Примечание: можно это сделать, поделив квадрат на 2 треугольника и сгенерировав точку в каждом при помощи равномерного распределения.

Хотя выглядит это немного неаккуратно, поскольку равномерное распределение не настолько интуитивно понятно, как кажется. Для более естественного распределения точек, можем взять значения из одной из моих любимых последовательностей Последовательности Хальтона (2.3)[можно почитать про нее в классной статье].

Последовательность Хальтона (2.3) генерируют точки в промежутке (0, 1) (0, 1) в R2. Чтобы заполнить квадрат точками, сгенерированными в этой последовательности, мы можем:

1. Найти минимальный ограничивающий квадрат, содержащий в себе Прямоугольник.
2. Сгенерировать N точек в (2.3) последовательности Хальтона.
3. Градуировать каждую точку по ширине (или высоте) минимального ограничивающего квадрата.
4. Переместить точку по верхней левой координате квадрата.
5. Отфильтровать все точки, которые не лежат в Квадрате.

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

В общем, (2.3) последовательность Хальтона генерируется просто; прочитайте про псевдокод в википедии (eng). Вот заполнение штрихом на 10000 точек.

image

Поскольку (2.3) последовательность Хальтона генерируется не рандомно, она создаёт одинаково выглядящие текстуры. Пара способов обойти это:

1. Градуирование и (по желанию) лёгкое раскачивание ограничительного квадрата, чтобы сместить центр последовательности.
2. Отбрасывание N точек с начала последовательности.
3. Рандомное отбрасывание малой части точек из последовательности (но осторожно, это создает больше шума).

Конечно, эти подходы можно совмещать. Экспериментируйте!

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

image
Провод Т


Конечно же, это не единственный подход к текстурированию.

Цвет


Чувствовать, какие цвета сочетаются друг с другом очень, очень сложно. Легко выбрать цвета, которые по твоему мнению хорошо сочетаются, но потом понять, что они совершенно не сочетаются и заставляют твою работу выглядеть в 10 раз хуже, чем в чёрно-белом варианте.

И я бы сказал, для генеративных художников этосоздает особую сложность. Стандартный способ варьировать цвета в генеративном искусстве вручную настраивать жёстко закодированные переменные и генерировать раз за разом картинку, пока не понравится. Игра с цветом и правда лучший способ научиться чувствовать, как их правильно использовать. Как мы можем его улучшить?

Вот мой подход, который я переделал из идеи Джошуа Дэвиса [https://joshuadavis.com/]. Вся суть:

1. В отдельной программе (я, например, использую AutoDesk SketchBook) сконструировать горизонтальную градиентную линию и сохранить в png.
2. Открыть png как пиксели в программе для создания генеративного искусства, и интерполировать между началом и концом градиента, используя функции плавности (функции с диапазоном выхода [0,1])

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

Мы будем использовать вот этот градиент для закрашивания точек в предыдущем примере (только точек в 20 раз больше).

image

Используемая нами функция плавности линейна по значению y. 0 обозначен на значении y верхней части квадрата, а 1 в нижней. Стоит заметить, что результат функции плавности (между 0 и 1) слегка смещается вместе с нормально распределённым случайным значением. Это помогает сформировать менее однородную структуру.

image

Отлично. И это всего лишь абсурдно простая функция плавности (и градиент, который я сделал за 5 минут). Представьте себе возможности!

Используем шум с пользой



Раз уж мы говорим о функциях плавности, а что там с шумом? Шум Перлина не совсем соответствует подходит для этой функции, так как его значения варьируются от -1 до 1. Но с умным mapping`ом, ограничением посторонних значений, модульной арифметикой с плавающей запятой и/или другими хитростями, конечно, мы можем сузить диапазон до [0,1].

Вот одна из моих серий Modular, в которой я использовал 2D шум как функцию плавности в цвете.

image

Смена цветов тут еле заметна, но в этом и суть. Они дают каждой форме раскрыться и придают глубину, не давя на смотрящего слишком большой и ненужной сложностью.

Если взглянуть внимательно, то можно заметить, что штрихованная структура тоже часть шума.

image

Стоит отметить, что простой шум Перлина может начать казаться безжизненным со временем. Попробуйте поэкспериментировать с фрактальным броуновским движением или разработать свою собственную шумовую функцию, с которой можно будет поиграться. Эссе Flow fields Тайлера Хобба хорошая вещь для углубления в тему (шум Перлина формирует бесконечные векторные поля, текучие поля это полезное обобщение).

Ощутимость



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

Это идея затронута подробно в Природе кода, которую я вам просто порекомендую, не цитируя Дэниэла Шиффмана. Дэниэл разделяет сложные физические проблемы на без проблем усваиваемые ломтики, упрощая реализацию каждой идеи. Делая свои творения, я часто запускаю на некоторое время физическую симуляцию и делаю снимок в определённый момент, который и становится финальной картиной.

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

image

В основе Пылевой чаши лежит симуляция рвущейся резинки.

image

Как по мне, эти картины живые. И неудивительно, правда. Они тесно связаны с нашим ведущим принципом:

Моделируйте свои работы на основе реальности

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

Подводя итоги, скажу, что следовать естественности в своих работах это то, что мне нравится делать. Мне не в тягость заставлять свой компьютер потратить чуть больше времени на генерацию текстур и симуляцию физики, чтоб в итоге получить более живое творение. Надеюсь, эта статья станет вашей отправной точкой в экспериментах с естественностью в ваших работах.

P. S. Здесь не было никакого кода не просто так. Эти идеи достаточно общие и применимые во многих языках и средах разработки, я не хотел бы никого отталкивать, заставляя перейти на что-то другое.
Подробнее..

Перевод Визуализация генеративных алгоритмов гифа, деревья, повторяющиеся и дифференциальные линии (на Python)

22.06.2020 02:19:54 | Автор: admin
image

ВВЕДЕНИЕ


Паттерны всегда меня очаровывали. Даже не важно какие. Я экспериментировал со многими: сети, листья и их переплетения, ветви, молнии, флокирование, очертания фигур, реки, скальный осадок, пейзажи, слизистая плесень, лишайники, взаимодействие и расплавление, клеточные автоматы, некоторые фракталы и другие штуки. Мне кажется, что самое приятное это то, как сложные и затейливые результаты можно получить от набора простых правил.

image

В последнее время мне были особенно интересны биологические образы и дифференциальный рост. У меня есть опыт в вычислительной математике, но не в биологии. Поэтому у меня мало знаний в том, как биологические системы работают. И всё же, я экспериментировал довольно много над воссозданием различных биологических закономерностей. Одна из сложностей заключается в том, чтобы попытаться воссоздать некоторые образы или закономерности максимально малым количеством простых правил.

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



ПРИЗНАНИЕ


Буду честным перед вами, я иногдаберу идею для своей работы из работ других художников. Особенно Джареда Тарбелла и Nervous System. К примеру, алгоритм, который я назвал Орбиталь (изображение ниже) сделан с очень сильной опорой на Happy Place Тарбелла.

image

Я указываю на это, потому что мне всегда было сложно понять, где программа, и в моем конкретном случае изображения, генерируемые этой программой, достаточно уникальны, чтобы рассматриваться, как отдельная работа.

INCONVERGENT (НЕСОСРЕДОТОЧЕННЙ)


Я начал работать с генеративными алгоритмами, когда должен был готовиться к экзаменам в университете. Именно поэтому я купил домен inconvergent.net, насмехаясь над тем, как я уклоняюсь от учёбы. Первое, что я сделал скопировал несколько алгоритмов Тарбелла с помощью Javascript/Canvas. Через некоторое время ко мне начали приходить уже собственные идеи.

image

Первым моим работающим алгоритмом, помимо Orbitals, был Hyphae. Он получился, когда я пытался воссоздать поведение гифы, сделанное Nervous System. На тот момент я не понимал, насколько сложный этот алгоритм на самом деле, и я потратил очень много времени, тщетно пытаясь сделать что-то сносное. Я все же смог сделать его, а еще вы можете прочитать работу Зигграфа (ENG) по этой теме, если интересно. Увлекательное чтиво!

КОД


Я выкладываю почти весь свой код на Github. Все следующие разделы имеют ссылку на соответствующий репозиторий. К сожалению, не все из них хорошо документированы или обновлены.

HYPHAE (ГИФА) [GITHUB]


Я начал экспериментировать с системой, где я выращивал связанные друг с другом круги, которые не могли накладываться друг на друга. Работает это так: вы где-нибудь помещаете начальный (круг), и задаёте ему радиус и направление движения. Затем пытаетесь добавить новый узел по периметру первого узла в направлении движения. Важно иметь направление движения, чтобы было немного колебания, и каждый раз угол немного отклонялся. Также обязательно каждый раз при добавление нового делаете радиус новых узлов немного меньше предыдущего.

image

Чтобы получить ветви, можно выбрать узлы наугад и попытаться вырастить новый узел более-менее перпендикулярно направлению движения ветви. И либо узлы столкнутся, либо вы получите новую ветку. Для более интересных результатов можно сделать углы отклонений пропорциональными ширине (радиусу) ветки. Более толстые ветки, как правило, прямее, чем тонкие. И вы, очевидно, можете сделать ещё много других вещей. Например, вы получите радикально разные результаты, если настроите то, сколько гибких ветвей вырастет по мере их утончения.

image

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

ДЕРЕВЬЯ [GITHUB]


Когда мы говорили о ветках, я понял, что можно упомянуть и маленький эксперимент с деревьями, ведь они похожи по сути.

image

Я хотел попробовать вырастить ветви таким же образом, как в Гифе, но только так, чтобы новые ветви появлялись только на концах других ветвей. К тому же, я не хотел обращать внимания на столкновения или что-нибудь подобное в этой симуляции. Получились не совсем деревья, но результат выглядит вполне реалистично, если не всматриваться сильно.

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

image

Чтобы придать деревьям эффект глубины, я добавляю тень к ветвям по мере их роста. Эта иллюзия далее развивается, добавляя все больше теней с одной стороны.

ПОВТОРЯЮЩИЕСЯ ЛИНИИ [GITHUB]


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

Рисовать фигуры на компьютере довольно легко. Линия состоит из ряда вершин (точек) с ребром (сегментом) между ними. Для создания треугольника вам нужно взять три ребра и соединить их тремя вершинами. Чтобы нарисовать круг, нужно сделать то же самое, только нужно достаточно много вершин, чтобы было невозможно увидеть, что это на самомо деле не круг. Если у вас появилсиь сомнения в подходе, то сразу скажу, что есть более сложные и точные способы рисования форм, но этот достаточно прост и точен.

Это значит, что рисовать эти линии так же, как Френсен, можно путём рисования округлых фигур со множеством вершин. Отслеживание формы немного сложнее, но есть несколько способов, которые можно опробовать. Я хотел, чтобы поведение имитировало то, как в реальности рисуется фигура, мало-помалу, при этом продолжая предыдущие линии. Алгоритм, который я придумал работал не совсем так. То есть, он не избегал столкновений, но результаты все равно выглядели очень хорошо.

image

Чтобы проследить контур, можно выбрать некоторые из соседних рёбер в предыдущей линии, рассчитать среднее направление этих рёбер и добавить вершину к текущей линии вдоль этого направления. Затем добавить несколько случайных движений для имитации рисунка от руки. Некоторое время такой подход работает довольно хорошо, но есть некоторая инертность, которую можно увидеть в результатах, форма адаптируется слишком медленно.
Количество шума, которое вы добавляете к каждой вершине, имеет решающее значение. Этот шум является тем, что заставляет всю систему создавать интересные формы, ибо коррекция формы вынуждает в процессе пытаться повторить как общее движение, так и некоторые случайные искажения.
Далее идет несколько более сложная система, которая тоже включает в себя линии.

ДИФФЕРЕНЦИАЛЬНАЯ ЛИНИЯ [GITHUB]


Дифференциал это тот алгоритм, который я давно хотел сделать. В какой-то момент решение просто само возникло у меня в голове, и мне удалось заставить алгоритм работать. Я хотел создать систему, которая вела бы себя так же, как поверхности в природе, которые разворачиваются друг из друга. Например, как грецкие орехи или слои капусты, (не буду даже рассказывать, сколько времени я провел времени за гуглением изображений красной капусты, разрезанной пополам), наш кишечник и некотороые виды листьев и цветочных лепестков. И, вероятно, многие другие вещи.

Прежде чем я начал прикидывать способы, я видел только Floraform, созданный Nervous System, но вам стоит увидеть ещё Cellular Forms Энди Ломаса. Другой важный документ, который я обнаружил гораздо позже, находится здесь.

Сначала я попытался использовать метод, основанный на фрактальной кривой Коха. Но со случайным ростом, а не симметричным и регулярным, как во фрактале. Я так и не доделал и быстро сдался. Однако, через некоторое время (плюс-минус шесть месяцев), я понял, что мог бы ввести новые узлы, пока кривая Коха растёт, но нужно заставить эти узлы смещаться относительно друг друга. Таким образом, они могли бы корректировать их позиции динамически, как жемчуг на верёвочке. Так они смогут держать нужное расстояние от других узлов (жемчужин).

Алгоритм выглядит следующим образом. Сначала мы создаем набор узлов, соединённых в какую-нибудь форму (круги или линии подойдут). Затем мы случайным образом вводим новые узлы между парами существующих узлов. В каждой итерации узлы будут пытаться оптимизировать свои позиции. Они будут хотеть быть рядом, но не слишком близко к своим двум соседям. В то же время они будут хотеть быть как можно дальше от всех других узлов. Обратите внимание, что здесь нет возможности их столкновения.

image

Есть ряд факторов, которые могут повлиять на поведение этой системы. Один из них то, как часто мы вводим новые узлы. Другой максимальное расстояние, в пределах которого узлы будут избегать друг друга. И самое интересное (на мой взгляд) то, как мы выбираем, куда вставлять новые узлы. Мы можем сделать это равномерно, как в гифке выше, или мы можем расставить приоритетные места, где изгибы кривой будут более острыми, как в гифке ниже.

image

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

image

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

image

image

А если генеративное искусство и визуализация данных, вас заинтересовали посмотрите другие посты degenerative_art, вот самые популярные на данный момент:

Подробнее..

Перевод Визуализация при помощи генеративных алгоритмов дифференциальная сетка (2D и 3D) и трещины

07.10.2020 22:05:40 | Автор: admin

ВВЕДЕНИЕ



image

Это развитие идей из публикации Визуализация при помощи генеративных алгоритмов: гифа, деревья, повторяющиеся и дифференциальные линии (на Python), однако вам необязательно читать ее все проекты, описанные здесь самодостаточны.

Все что вам необходимо знать: последнее время автору были особенно интересны биологические образы и дифференциальный рост. В посте есть результаты экспериментов с различными биологическими и физическими закономерностями, в частности дифференциальной сеткой, в том числе в 3D, и трещинами.



ДИФФЕРЕНЦИАЛЬНАЯ СЕТКА [GITHUB]



После того как я получил дифференциальную линию (подробнее в посте на HABR), очевидным следующим шагом было попытаться создать нечто подобное в трех измерениях. И единственный вариант это заставить саму линию двигаться в трех измерениях. Однако, это не выглядит очень интересным. Вместо этого, я решил выбрать сочетание формы поведения притяжение/отклонение дифференциальной линии с функцией роста Гифы. В общем-то, я хотел сделать треугольные сетки, которые росли бы наружу без самопересечения или столкновений. Делать это непосредственно в трех измерениях казалось немного трудным, поэтому я решил начать с двухмерной версии.

image

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

Основной момент в работе с сеткой заставить сетку делать различные операции самобалансировки в процессе роста. Есть несколько вещей, которые вы можете попробовать:
  • Разделите слишком длинные края.
  • Избегайте вставки новых вершин, где плотность вершин уже слишком высокая.
  • Переворачивайте рёбра, чтобы уменьшить длину.
  • Добавьте силу, которая будет заставлять треугольники пытаться быть приблизительно равносторонними.


В приведенной выше анимации используются все эти принципы.

Теперь мы уменьшаем размер треугольника и добавляем немного структурности.

image

Расчёт был на то, что этот набор правил будет напоминать рост слизи или, что вероятнее, лишайника. Оказывается, стандартная версия этого алгоритма очень похожа на определенные виды лишайников. И это похоже ещё на рост печеночных мхов, как подсказали мне в Твиттере.

Изначально я контролировал рост, при помощи выбора случайных рёбер, проверке на то, внешние ли они и определении, могу ли я прикрепить новый треугольник к этому ребру. Проблема этой стратегии в том, что в конечном итоге большинство выбранных рёбер будут на внутренней стороне структуры. Это означает, что вы потратите много ресурсов на проверки рёбер, с которыми вы потом ничего не сделаете.

Есть довольно очевидное решение этой проблемы. (И, как обычно, когда я говорю очевидно, я имею в виду, что на понимание этого у меня ушло несколько месяцев). Вместо того, чтобы выбирать случайные рёбра и проверять, можно ли на них сделать новый треугольник, вы можете использовать источники пищи. Сначала вы случайным образом позиционируете источники пищи по всему пространству. Тогда у вас будет что-то происходить каждый раз, когда ребро в структуре натыкается на один из этих источников. Например, если вы резко увеличите темп роста, когда сетка добирается до источника пищи, вы получите что-то вроде этого:

image

Если вы дадите этой симуляции поработать некоторое время, то сможете получить много интересных результатов. Вот версия, где цвет каждого треугольника постепенно меняется в зависимости от того, когда он был создан. Цвет постепенно меняется от белого к черному, а затем мгновенно переходит обратно в белый. В первый раз я сделал это случайно, но, как вы можете видеть, это придаёт визуализации отличный трехмерный эффект.

image

ДИФФЕРЕНЦИАЛЬНАЯ СЕТКА В 3D [GITHUB]


Так как дифференциальная сетка, похоже, работала неплохо, я решил сделать попытку воссоздать то же поведение в трёх измерениях. В некотором смысле это просто вопрос добавления третьего измерения и работы в нём. Тем не менее, было несколько других проблем.
Во-первых, избегать столкновений немного труднее в 3D. Во-вторых, сделать сетку последовательной тоже сложнее. (Я использую вариацию Half-Edge структуры данных для представления сетки и всех операций на ней.)

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

Одним из таких лучших способов является Floraform, созданный Nervous System. Другим (хотя, грубо говоря, это не сетка) является Сellular Form Энди Ломаса.
Если вы хотите поэкспериментировать с 3D-сетками самостоятельно, я рекомендую попробовать Blender, который имеет полную поддержку Python API. Вы можете увидеть мой пример реализации здесь. Вы также можете попробовать Processing в сочетании с HE_Mesh Фредерика Вануэтта.

image

Это изображение рендеринга сетки сделано в Blender, с помощью движка Blender Cycles Rendering. Как вы можете видеть, у объекта на изображении довольно потрёпанный вид. Это результат выбранной стратегии роста: как и в методе источника пищи, используемом для создания дифференциальной сетки, рост этой сетки контролируется путем применения параметра интенсивности роста. Вершины с высокой интенсивностью роста будут более склонны двигаться, чем вершины с более низкой, что в свою очередь приводит к добавлению новых вершины к сетке.

image

При запуске моделирования некоторым вершинам задана интенсивность роста 1, в то время, как у остальных вершин интенсивность роста равна 0. По мере моделирования, интенсивность роста будет постепенно распространяться на соседние вершины, подобно тому, как тепло распространяется по куску металла.

Для того, чтобы сетка росла наружу, внешним рёбрам сетки случайным образом задана интенсивность роста 1 в ходе моделирования. Если мы сделаем это рассеянным образом, мы получим потрёпанные сетки, как на изображении сверху. С другой стороны, если применить интенсивность роста на краю более равномерно, результаты будут больше похожи на второе изображение

ТРЕЩИН [GITHUB]


Я уже упоминал Джареда Тарбелла в этом тексте, но упомяну его еще раз. Одним из первых увиденных мной произведений генеративного искусства, на которое я обратил внимание, было Substrate Тарбелла. Это гениальный алгоритм во всей его простоте. Линии растут в определенном направлении до тех пор, пока они не достигнут границы территории, или до тех пор, пока не столкнутся с другой линией. Когда линия останавливается, по крайней мере одна новая линия появляется перпендикулярно одной из существующих линий в произвольном положении.

image21.png

Воссоздание похожих на города структур Substrate само по себе упражнение интересное. Однако, я хотел объединить (частично) поведение Substrate с другими особенностями ранее упомянутого алгоритма пересечения листьев. Цель была имитировать сетку трещин, которые можно увидеть на хрупких материалах, таких как стекло или фарфор. Вы, возможно, видели это сами, если вам хоть раз приходилось ронять телефон или если у вас есть старая посуда. В изобразительном искусстве эти трещины называются Кракелюр.

image
Подобно методу, используемому в алгоритме пересечения листьев, мы распространяем несколько источников пищи по пространству. Затем мы генерируем любое количество изначальных трещин. Последующие этапы роста этих трещин контролируются следующим алгоритмом:
  • Найти все источники в поле зрения трещины (FOV). Изменение поля зрения даст очень разные результаты; большее FOV сделает трещины более извилистыми.
  • Рассчитать (массу) центр источников в поле зрения.
  • Сделать шаг к центру масс.
  • Мы завершаем трещину, если она столкнулся с другой или если нет источников в FOV.


В дополнение к контролю роста трещин, мы должны добавлять новые трещины. Стратегия, используемая в изображениях, показанных здесь, заключается в том, чтобы случайным образом создавать новые трещины от кончика трещин, которые ещё активны (т.е. ещё не столкнулись ни с чем). Частота возникновения новых трещин существенно повлияет на конечный результат.

Если вы когда-то видели разбитый экран телефона, вы могли заметить, что трещины редко распределены равномерно: плотность трещин, как правило, больше вблизи точки удара. Для имитации этого эффекта вы можете ввести скорость трещин. По мере роста трещины скорость постепенно уменьшается. Когда появляется новая трещина, она наследует значение (например, 0,8) текущей скорости пркдешественницы. В этом случае скорость трещин используется не для контроля темпов роста, а для регуляции скорости создания новых трещин. Этот эффект выглядит как на следующем изображении.

image
Подробнее..

Перевод Песочный алфавит при помощи генеративных алгоритмов

19.10.2020 00:12:27 | Автор: admin
image

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

Это развитие идей из публикаций:

Визуализация при помощи генеративных алгоритмов: гифа, деревья, повторяющиеся и дифференциальные линии (на Python)

Визуализация при помощи генеративных алгоритмов: дифференциальная сетка (2D и 3D) и трещины

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

ПЕСОЧНЙ СПЛАЙН [GITHUB]


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

image

Идея основана на концепции B-сплайнов. В математике B-сплайн представляет собой плавную кривую, которая нарисована из ряда узлов (контрольных точек) без обязательного прохождения через сами эти узлы. Если вы переместите немного узлы, плавная кривая кривая будет следовать дальше. И если вы заставите узлы потихоньку двигаться, сплайн постепенно станет все более рассеянным. Вы можете увидеть это в анимации ниже.

image

В этой анимации сплайн начинается справа и движется против часовой стрелки. Вы также можете заметить, чем дальше вдоль сплайна, тем больше становится уровень шума. Это не имеет ничего общего с самим сплайном, но это хороший способ сохранить исходный узел в начальном положении.

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

Такое поведение, и техника рисования, во многом похожи на несколько работ Тарбелла, в том числе Sand Dollar, Limb Sand Stroke, Sand traveller и Sandstroke. Отсюда и пошло название. Несколько человек указали мне, что эти образы также очень напоминают Аттрактор Лоренца, хотя метод используется немного другой.

image

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

ДИФФЕРЕНЦИАЛЬНАЯ РЕШЁТКА [GITHUB]


При работе над дифференциальной линией, дифференциальной сеткой и дифференциальной сеткой в 3d наиболее утомительной частью было управление структурой данных. Отчасти потому что я решил научиться использовать half-edge структуры данных в этом процессе. И ещё потому что это у меня так и не получилось. И, наконец, потому что я писал его в Cython, который был в новинку для меня.

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

Держа это в голове, я начал создавать дифференциальные решетки. Часть алгоритма очень похожа на дифференциальную сетку. Он состоит из соединённых узлов, и соединённые узлы пытаются оставаться близко друг к другу. Он также сохраняет принцип, когда каждый узел пытается избежать близости со всеми несвязанными узлами в определенном радиусе. Важная особенность в том, что соединения между узлами перерассчитываются перед каждой итерацией. Это означает, что нам нужен хороший способ решить, должны ли два близлежащих узла считаться соседями или нет.

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

image

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

Благодаря этому вся задача сводится к решению, куда разместить новые узлы, и как часто новые узлы должны появляться. В этих примерах новые узлы появляются в областях, где локальная плотность узлов достаточно низка. Это приводит к тому, что новые узлы часто появляются за пределами существующей структуры. Получается что-то наподобие слизистой плесени, которая постепенно растет наружу.

Эта система не имеет какого-либо распределения истончиков пищи (точек, которые ускоряют рост), что является интересным аспектом для изучения. Например, такая простая система каким-то образом сможет в теории повторить Токийскую железнодорожную систему или показать какое-нибудь другое интересное поведение (но это не точно).

image

Эта система реализована с помощью pyCUDA, что означает, что все расчеты расстояний и расчёты соседства могут быть сделаны на GPU. Поэтому это, вероятно, один из самых быстрых алгоритмов, которые я когда-либо реализовывал. Можно сделать системы с сотнями тысяч узлов удивительно быстро, с учетом количество вычислений.

Ниже изображение с около 80 000 узлами, которое было нарисовано на моём механическом плоттере.

image

ПЕСЧАНЕ ТВОРЕНИЯ [GITHUB]

При работе над песочными сплайнами у меня получились несколько промежуточных результатов, которые напомнили мне текст, написанный от руки/ Вместо того, чтобы напрямую пытаться сделать что-то, что выглядело бы как написанный текст, я начал экспериментировать с генерацией малых Песчаных творений.

Я попробовал несколько разных подходов, но следующий метод привел к наиболее приятным результатам:

  • Создать несколько случайных контрольных точек из равномерного распределения, ограниченного сферой.
  • Расположить их в произвольном порядке.
  • Создать B-сплайн из контрольных точек в том же порядке.

image

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

С небольшими изменениями параметров можно получить совершенно разные результаты, как например в примере ниже.

image

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

ПЕСЧАНЕ ЗНАКИ [GITHUB]


После того как я опубликовал нескольких своих Песчаных Творений, мне предложили попробовать сделать свой шрифт. Я не пробовал сделать это ранее, но зато пробовал различные методы создания написанного от руки текста, путем объединения нескольких песчаных творений, из предыдущего раздела. Как вы можете видеть ниже, даже очень простые комбинации песчаных творений могут создать довольно приятное асемическое письмо.

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

image

Есть ряд вещей, с которыми можно поэкспериментировать даже в этой простой конфигурации:

  • Количество контрольных точек на знак;
  • Расстояние между знаками;
  • Форма знаков;
  • Положение знаков относительно горизонтальной центральной линии;
  • Внутренний порядок контрольных точек в знаках;
  • Количество знаков в слове;
  • Как письмо делится на строки;
  • И так далее ...

Не говоря уже о том, что все эти вещи предполагают написанный слева направо, более или менее латинский, написанный от руки текст.

Ниже приведен пример одной из конфигураций, которую считаю лучшей до сих пор.

image

Есть ещё такое видео того, как мой плоттер выписывает текст.

Наконец, я хотел бы обратить ваше внимание на Lettres de ma mre, сделанную пионером генеративного искусства Верой Молнэр.
Больше работ автора можно увидеть на сайте Inconvergent

Предыдущие проекты этого же автора:


А если генеративное искусство и визуализация данных, вас заинтересовали посмотрите другие посты degenerative_art, вот самые популярные на данный момент:


Подробнее..

Перевод Поле течения алгоритмы применения

18.11.2020 14:04:51 | Автор: admin

Поля течения - невероятно мощный и гибкий инструмент для создания необычных линий. Это один из основных инструментов, который я несколько лет использовал в моих генеративных произведениях, и я осознаю, что обращаюсь к нему снова и снова. Вполне возможно, что я использовал его столько раз при написании кода, сколько не использовал никто другой.

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

СЕТКА УГЛОВ

Поля течения основаны на сетке (grid). Грубо говоря, сетка покрывает всю картину. В каждой точке сетки хранится угол. Сетка должна храниться в виде 2D массива чисел с плавающей запятой. Каждая единица в сетке хранит значение угла и одновременно представляет собой точку на сетке.

При созданию сетки надо выбрать ее разрешение. Другими словами, расстояние между точками в сетке. Чем выше разрешение, тем мельче детали, которые вы можете проработать, и плавнее линии. Недостатком является то, что может пострадать функциональность, если увеличите его слишком сильно. Обычно я использую около 0.5% ширины изображения в качестве расстояния между точками. Ещё я использую ту же длину для длины пространства между точками, чтобы упростить расчёты и избежать ошибок точности плавающей запятой.

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

Предположим, что перед нами картина 1000 x 1000 пикселей, и мы хотим залить ещё 50% площади вне ее границ. Мы можем установить нашу сетку вот так (псевдокод):

left_x = int(width * -0.5)right_x = int(width * 1.5)top_y = int(height * -0.5)bottom_y = int(height * 1.5) resolution = int(width * 0.01) num_columns = (right_x - left_x) / resolutionnum_rows = (bottom_y - top_y) / resolutiongrid = float[num_columns][num_rows]default_angle = PI * 0.25for (column in num_columns) {    for (row in num_rows) {        grid[column][row] = default_angle    }}

Если бы мы запустили программу для визуализации кода этой сетки в таком виде, то это выглядело бы приблизительно так (качество отрегулировано для лучшей видимости).

Стандартная сетка со всеми углами, установленными на pi* 0.25Стандартная сетка со всеми углами, установленными на pi* 0.25

Теперь у нас есть поле, с которым можно работать. Но к сожалению, пока будут рисоваться только прямые линии. Поработаем над этим. Пока давайте заставим сетку проворачиваться в процессе изменения положения точек на картине.

for (column in num_columns) {     for (row in num_rows) {         angle = (row / float(num_rows)) * PI         grid[column][row] = angle     }}

Это выглядит как-то так:

Изогнутая сеткаИзогнутая сетка

РИСОВАНИЕ КРИВХ ЛИНИЙ ЧЕРЕЗ ПОЛЕ

Теперь мы используем сетку для рисования линий. Вот базовый алгоритм: выбираем начальную точку. Находим подходящую точку рядом на сетке. Берём угол с этой точки на сетке и делаем небольшой шаг в сторону этого угла. На новом месте мы снова делаем поиск и повторяем предыдущие шаги раз за разом. Выглядит это так (псевдокод).

// starting pointx = 500y = 100begin_curve()for (n in [0..num_steps]) {    draw_vertex(x, y)    x_offset = x - left_x    y_offset = y - top_y    column_index = int(x_offset / resolution)    row_index = int(y_offset / resolution)    // ПРИМЕЧАНИЕ: обычно на этом этапе стоит проверить границы    grid_angle = grid[column_index][row_index]    x_step = step_length * cos(grid_angle)    y_step = step_length * sin(grid_angle)    x = x + x_step    y = y + y_step}end_curve()

Если мы это проделаем только для одной кривой, это будет выглядеть как-то так:

Рисование единственной простой кривой на полеРисование единственной простой кривой на поле

Нам нужно выбрать значения для нескольких ключевых параметров для рисования линий: step_length, num_steps, и starting position (x, y). Step_length - самый простой параметр. Как правило, он должен быть настолько мал, чтобы нельзя было увидеть никаких резких углов на кривой линии. Как по мне, он должен быть около 0.1%-0.5% ширины картины. Я делаю больше, если мне нужен более быстрый рендеринг, и меньше, если есть углы, которые надо подкорректировать. Другие переменные требуют больше разъяснений.

num_steps

Значение num_steps повлияет на текстуру результата. Небольшие линии могут выглядеть более пушистыми. Длинные - более жидкими. Вот пример одного и того же кода, выполняемого с разными значениями num_steps. Для начала, с короткими линиями:

С короткими линиямиС короткими линиями

И теперь с длинными:

С длинными линиямиС длинными линиями

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

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

Unfenced ExistenceUnfenced ExistenceFragments of ThoughtFragments of Thought

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

Loxodography 0.26Loxodography 0.26

starting_point

Все кривые линии должны где-то начинаться. Обычно я использую один из трёх вариантов выбора начальной позиции:

  • Использовать стандартную сетку для начальных позиций

  • Использовать единообразный случайный выбор точек

  • Использовать круговую укладку

  • Стандартная сетка - самый простой вариант, но иногда она может казаться чрезмерно негибкой. Однотипно случайный выбор кажется свободнее, но он сделает некоторые места либо слишком нагромождёнными, либо пустыми, а это не всегда то, что нужно. Подход укладки круга самый сбалансированный: всё достаточно хорошо распределено и с достаточной рандомностью, из-за чего выглядит более расслаблено. Эти различия еле заметны, если рисовать просто длинные линии без цвета или других особенностей:

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

Сетка - Случайный выбор - Круговая укладкаСетка - Случайный выбор - Круговая укладка

Но если укоротить линии, разница станет очевидной.

Сетка - Случайный выбор - Круговая укладкаСетка - Случайный выбор - Круговая укладка

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

ДЕФОРМАЦИЯ ВЕКТОРОВ

Важная дизайнерская дилемма: каким образом деформировать векторы в поле. Выбранный способ определит форму искривлений. Определит, будут ли это завитки, резкие повороты или накладывающиеся друг на друга линии.

Шум Перлина

В 90% случаев шум Перлина используется для отстройки векторов. Это удобно и просто, ибо даёт гладкие и продолжительные значения параметров по всей 2D плоскости. Есть ещё разные параметры шума - их множество от значимых до почти не влияющих на итоговую картину. Все это очень легко использовать в Processing. Функция noise() задает значения шума Перлина (между 0,0 и 1,0) с учётом координат.

Вернувшись к коду, мы вместо вставки default_angle можем сделать что-то такое:

for (column in num_columns) {  for (row in num_rows) {      //noise() в // Processing работает лучше всего в середине      // точки примерно 0.005, поэтому уменьшаем до      scaled_x = column * 0.005      scaled_y = row * 0.005      // получаем наше значение шума между 0,0 и 0,1      noise_val = noise(scaled_x, scaled_y)      // перенести значение шума к углу (между 0 0 2 * PI)      angle = map(noise_val, 0.0, 1.0, 0.0, PI * 2.0)      grid[column][row] = angle  }}

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

Использование шума Перлина в углахИспользование шума Перлина в углах

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

Непродолжающиеся деформации

Важный аттрибут для деформации, который вы можете задать - это будет ли деформация продолжающейся или нет. Под продолжающейся я имею в виду плавный переход между соседними векторами, без прыжков Как я уже упоминал, шум Перлина как раз так и работает. У меня есть своя техника деформации, у которой есть это качество, и которую я люблю использовать. Когда вы используете продолжающуюся деформацию, кривые не пересекают друг друга, они плавные и систематизированные. Однако стоит поэкспериментировать ещё и с непродолжающейся деформацией векторов. Простой пример, как это можно сделать, - начать с шума Перлина, но округлить угол каждого вектора до pi/10:

Так мы получим более скульптурные, каменистые формы. Если увеличим до pi/4, то результат станет странным:

Как вариант, можно выбрать случайный угол (между 0 и pi) для каждого ряда векторов:

Или выбрать случайный угол для каждого вектора.

Суть в том, что и непродолжающиеся деформации тоже могут генерировать хорошие штуки.

СОЧЕТАНИЕ С ДРУГИМИ ТЕХНИКАМИ

Существует бесконечное множество способов экспериментов с полями течения и использования их по-новому. Вот несколько вещей, опробованных мною, вам для вдохновения.

Можно установить минимально возможное расстояние между кривыми. На каждой стадии кривой проверяйте, не слишком ли близко другая линия. Если близко, то останавливайтесь. Я использовал эту технику на зеркальном рисунке в 2019 году:

Mirror Removal #5Mirror Removal #5

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

Side Effects Inclue\dSide Effects Inclue\d

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

Festival Notes 0.161Festival Notes 0.161

Можно делать переход между соседними линиями для создания контура многоугольника. Если интерполировать между двумя соседями (возможно, с нелинейным ослаблением), то можно получить плавные, прекрасные формы:

Stripes 0.30Stripes 0.30

Можно вставлять объекты, которые деформируют сетку вокруг самих себя. В Ectogenesis я просчитал, как вода будет двигаться и преломляться вокруг объекта.

(Отмечу, что это было сложно)

Суммируя

Это почти всё, что я могу сказать о полях течения. Я думаю, что как и в любой технике, самое важное - понять их от А до Я, а затем расслабиться и делать все по-своему. Просто не используйте шум Перлина, и всё.

Популярные посты по генеративному искусству:

Подробнее..

Перевод Сняли забавный фильм, сценарий для которого написал GPT-3

23.10.2020 20:07:00 | Автор: admin

В Солиситорах (Solicitors), новом короткометражном фильме, снятым парой студентов-старшекурсников Университета Чапмана, все начинается с женщины, сидящей на диване и читающей книгу. В дверь раздается стук. Она встает, открывает дверь и обнаруживает за ней потного, дерганного человека с растрепанными волосами. Я Свидетель Иеговы, - говорит он. Женщина не выглядит впечатленной и отвечает: Прошу прощения, я не говорю с солиситорами". Мужчина пытается удержать ее внимание - У меня есть отличная история.

В фильме есть два сюжетных твиста. Один - как и во многих короткометражных фильмах по О.Генри откровение последней минуты, которое полностью меняет наше представление о всех предыдущих событиях. Второй раскрывается буквально сразу. Не буду спойлерить (да ладно вам - фильм длится всего несколько минут), но второй как раз является важным - весь сценарий, начиная с 20 секунды фильма был написан искусственным интеллектом.

Самой большой проблемой для меня стало, когда я снимался в фильме, написанном в основном ИИ, найти мотивацию для моего персонажа и понять намерения в моем диалоге.

Хотя нет недостатка в прекрасных фильмах, написанных о передовом искусственном интеллекте, от Матрицы до Терминатора и от них до Ex Machina, очень немногие могут сейчас говорить, что их автором стал передовой искусственный интеллект. Являются ли Solicitors примером грядущих медиаразвлечений, основанных на технологиях?

Я нашел код AI [который мы использовали], пока сидел на обучении, пытаясь изобразить заинтересованность Zoom`ом , - сказал режиссер и оператор короткометражного фильма Джейкоб Ваус. Меня сразу зацепило. Мне понравилось вставлять короткие истории, которые я написал, и смотреть, куда AI в итоге приводит сюжет, или вводить безумное начало и смотреть, куда пойдет эта история. Поскольку мы изучаем кино, нам сразу же понравилась эта идея. Может ли он написать сценарий? Какой контент мы могли бы сделать, чтобы продвинуть такой фильм? Насколько творческими мы могли бы стать? "

Получив человеческих помощников, AI создал сценарий, включая его финальный сюжетный поворот. (Вы можете прочитать сценарий в Интернете здесь). Мы думали, что это было так забавно, но также в некотором роде блестяще то, как AI довел сценарий до таких крайностей, - сказал Эли Вайсс, продюсер Solicitors. С точки зрения сторителлинга, он дал все, что вы хотите от истории, даже если это получилось странновато.

Ваус сказал: Мы умирали от смеха, когда впервые прочитали это. То, как он использует детали с самого начала, будто они имеют смысл, но в то же время бессмысленны, для меня невероятно.

Позаботьтесь и об актерах. Самой большой проблемой для меня стало, когда я снимался в фильме, написанном в основном ИИ, найти мотивацию для моего персонажа и понять намерения в моем диалоге., - сказал актер Эштон Херрилд, который играет мужчину на пороге. Обычно работа актера заключается в том, чтобы представить обстоятельства и персонажа, которые говорят и делают такие вещи. Но в сценарии, написанном искусственным интеллектом, не было никакого скрытого смысла, который нужно было найти - только отдавать .

Машины, снимающие фильмы

Это не первый раз, когда AI. был использован для написания сценария. Несколько лет назад актер Зак Брафф исполнил машинный монолог в роли своего персонажа Джей Ди из Клиники. Больница во многом похожа на среднюю школу, - говорится в ней. - Самый удивительный человек умирает, а ты единственный, кто хочет украсть вещи у его отца.

Эти генеративные алгоритмы, обученные на больших объемах данных, могут использоваться для создания нового, но до странности знакомого контента путем поглощения огромного количества материала, будь то романы о Гарри Поттере, книги Песнь льда и пламени или сценарии любимых комедийных фильмов. В результате получается современная технически подкованная версия метода нарезок Уильяма Берроуза: сюрреалистическая техника создания чего-то нового из чего-то существующего путем физического разрезания и склеивания в случайном порядке. Конечные продукты в случае алгоритмически сгенерированных скриптов часто бывают забавными. Однако они обычно не делают это особенно хорошо - по крайней мере, в том смысле, в котором мы можем оценить голливудский сценарий как хороший.

Поскольку у фильма редко бывает один-единственный создатель сценария, идея интеграции инструментов искусственного интеллекта в цикл написания и разработки не так уж и революционна, как может показаться.

Однако GPT-3 это большой шаг вперед. Эта версия алгоритма генерации текста почти всерьез считалась слишком опасным для массового доступа (до момента релиза финальной версии ). GPT-3 представляет собой нейронную сеть обработки естественного языка, созданную OpenAI. Предварительно подготовленная языковая модель GPT, с добавлением нескольких предложений в качестве начала сценария о человеке, появляющемся на пороге, убедительно сгенерирует текст, который будет соответствовать исходному материалу - по крайней мере, по тону и стилю. Это произвело фурор после его выпуска. Британская газета Guardian, издание, которое в разное время заказывала работу у некоторых из величайших журналистов мира, опубликовала статью, написанную GPT-3. Они озаглавили ее: "Робот написал всю статью. Тебе еще не страшно, человек?"

В 1959 году британский ученый и писатель К. Сноу написал знаменитое эссе под названием Две культуры, в котором утверждал, что интеллектуальная жизнь всего западного общества разделилась на два лагеря: точные науки и инженерное дело с одной стороны и гуманитарные науки с другой. Эти два лагеря, как он утверждал, нельзя совмещать ни при каких условиях. Сегодня кажется, что стены между этими двумя культурами рушатся быстрее, чем многие думают.

Лучшие студии мира больше не классические студии в голливудском стиле. Это технологические компании, такие как Netflix, Apple, Hulu и Amazon, и, как любая стоящая технологическая компания, они часто используют высокотехнологичные решения для творческих задач. Netflix, например, не скрывает роли больших данных в определении того, какие проекты заказывать. Наряду с невероятно глубокими карманами, эта точность в отношении того, что они должны и что не должны делать, помогла им выбрать лучших со скоростью, которая заставила бы Усэйна Болта замедлиться, чтобы перевести дух.

Другие продвигают технологическое производство еще дальше. AI консалтинговые компании, такие как британская Epagogix, которую когда-то профилировал Малкольм Гладуэлл для The New Yorker, используют данные не только для того, чтобы сказать, стоит ли продолжать проект, но и для того, чтобы внести предложения о том, как эти проекты можно творчески изменить, чтобы сделать их более прибыльными. Тем временем медиа-футурист и создатель алгоритмических фильмов Алексис Кирк отвечает за создание фильмов, которые разветвляются на основе физиологических реакций тех, кто их смотрит.

Еще один инструмент для авторов

Легко посмотреть на такой фильм, как Солиситоры, и увидеть проблески будущего творчества, в котором сценаристы будут больше не нужны. Но это не совсем точно. Каким бы хорошим ни был GPT-3, маловероятно, что ведущие сценаристы, такие как София Коппола или Аарон Соркин, будут дрожать в своих высокооплачиваемых голливудских ботинках из экологически чистых материалов в ближайшее время. Такие инструменты, как GPT-3, в конечном итоге - это всего лишь инструменты. Они будут играть роль в будущем развлечений, но не заменять, а дополнять их.

"Поскольку у фильма редко бывает один-единственный создатель сценария, идея интеграции инструментов искусственного интеллекта в цикл написания и разработки не так уж и революционна, как может показаться". - Сказал Кирк.

По словам Кирка, эти инструменты представляют собой следующий шаг в процессе, уже проторенном программами, которые мы теперь принимаем как должное, например, скромная проверка орфографии. "Сценаристы, продюсеры, режиссеры, редакторы сценариев и т. д. накопили огромный опыт", - сказал он. - "Хотите уменьшить количество наречий и прилагательных в вашем письме? Для этого есть алгоритм. Хотите, чтобы диалоги ваших персонажей отличались друг от друга? Для этого есть алгоритм. Хотите создать альтернативные, менее штампованные, переписанные страницы, сохраняющие их общий смысл? Для этого есть алгоритм.

AI который автоматически сгенерирует несколько страниц научно-фантастических идей или идей в стиле фильма ужасов, чтобы вдохновить писателя-человека, - это просто еще одна итерация этого, как и бот, который смотрит на ваше письмо и сообщает вам, принесли ли сценарии такого типа деньги в прокате в прошлом. (Программное обеспечение GPT-3, используемое Ваусом и Вайссом, называется Shortly Read. Его веб-сайт описывает его как средство помощи писателю. "Просто нажмите кнопку, и ИИ продолжит писать вашу историю, генерируя новые творческие идеи и сюжетные наработки". )

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

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

Подробнее..

Оживление портрета с помощью Realistic Neural Talking Head Models

11.03.2021 02:07:38 | Автор: admin
Добрый день, увадаемые читатели.
В прошлом году я работал над одним интересным проектом по оживлению портрета с помощью технологии Realistic Neural Talking Head Models на основе генеративных нейронных сетей. В проекте я использовал разработку центра Samsung AI в Москве под названием Few-Shot Adversarial Learning of Realistic Neural Talking Head Models. В этой статье я расскажу как можно попробовать эту технологию на практике. Кому интересно, прошу под кат.

image

О разработке Neural Talking Head Models можно прочитать в статье авторов.

image

Здесь мы будем использовать реализацию подхода на PyTorch из этого репозитория. Автор реализации Vincent Thvenin исследователь из французского De Vinci Innovation Center.

Начнем работу с Realistic-Neural-Talking-Head-Models. Лучше использовать Python версии 3 чтобы избежать возможных проблем с пакетами. Клонируем репозиторий и переходим в папку.

git clone https://github.com/vincent-thevenin/Realistic-Neural-Talking-Head-Models.gitcd Realistic-Neural-Talking-Head-Models


Скачаем необходимые файлы отсюда. У нас появятся два файла: Pytorch_VGGFACE_IR.py (PyTorch код) и Pytorch_VGGFACE.pth (Pytorch модель).
Нам не нужно обучать модель, так как автор предоставил нам предобученные веса на Google Drive.

Установим необходимые библиотеки matplotlib, opencv и face_alignment

pip install matplotlib opencv-python face_alignmentsudo apt-get install python-tk


Нам также нужно установить драйвер NVIDIA, который требуется для запуска embedder_inference.py. Скачать драйвер NVIDIA для вашего конкретного GPU можно отсюда. Например для Tesla K80

wget http://us.download.nvidia.com/tesla/440.33.01/NVIDIA-Linux-x86_64-440.33.01.run


Сделаем файл исполняемым и установим драйвер:

chmod +x NVIDIA-Linux-x86_64-440.33.01.runsudo ./NVIDIA-Linux-x86_64-440.33.01.run


В некоторых случаях этот вариант падает с ошибкой fails due to X server (подробно описано здесь).

Можно установить драйвер NVIDIA другим способом. Сначала узнаем какой графический драйвер подходит для нашей системы:

ubuntu-drivers devices


Затем установим рекомендуемый драйвер NVIDIA и сделаем ребут:

sudo apt-get install nvidia-384


Наконец нам нужно установить PyTorch согласно установленной версии CUDA. Узнаем какая версия CUDA установлена в системе

nvcc --version


Скажем у нас стоит CUDA v10.1

Cuda compilation tools, release 10.1, V10.1.243


Перейдите на сайт PyTorch и выберите соответствующую инструкцию для вашей ОС по установке PyTorch

pip install torch torchvision


Давайте запустим embedder (embedder_inference.py) на видео или изображениях человека и сгенерируем эмбеддинг вектор:

python embedder_inference.py


Результат:

Saving e_hat......Done saving


Вы получите два файла: e_hat_images.tar и e_hat_video.tar. Давайте запустим finetuning_training.py:

python finetuning_training.py


Вывод будет таким:

What source to finetune on?0: Video1: Images


Введем 1 для изображений

Downloading: "https://download.pytorch.org/models/vgg19-dcbb9e9d.pth" to /home/vladimir/.cache/torch/checkpoints/vgg19-dcbb9e9d.pth...avg batch time for batch size of 1 : 0:00:12.463398[0/40][0/1]     Loss_D: 2.0553  Loss_G: 5.2649  D(x): 1.0553    D(G(y)): 1.0553


Скрипт выполняет обучение на изображениях.
В результате мы получим примерно такое изображение

image

Видно, что качество результата низкое.
Теперь попробуем обучение на видео

avg batch time for batch size of 1 : 0:00:13.738919[0/40][0/1]     Loss_D: 2.0539  Loss_G: 3.3976  D(x): 1.0539    D(G(y)): 1.0539


image

В этот раз значения функции потерь ниже и конечный результат выглядит лучше.
Результат обучения finetuning_training на нашем собственном изображении

image

и оригинал

image

Здесь также есть скрипт webcam_inference.py для тестирования генерации изображений по видео с камеры. Запустим the webcam_inference.py

python webcam_inference.py


Этот скрипт запускает модель на основе персоны из вектора эмбеддинга и потока с камеры, выполняет только инференс. Скрипт генерирует три изображения: facial landmark, оригинал (фото с камеры) и фейк. В этот раз инференс выполняется на модели дообученной на видео

image

image

Сейчас попробуем модель дообученную на изображениях

image

image

Инференс выполняется очень медленно. У меня запуск занял несколько минут на виртуалке на Google Cloud с NVIDIA GPU.
Мы можем переобучить генератор на видео чтобы получить лучше результат. Автор проекта утверждает, что генератор был обучен на 5 эпохах что не является оптимальным.

Для обучения мы можем использовать датасет VoxCeleb2. Чтобы скачать датасет вы должны запросить доступ к нему заполнив специальную форму.
Датасет разбит на 9 частей. Для скачивания всего датасета вы можете воспользоваться моим bash скриптом, доступным на github. Запустим скрипт для загрузки датасета

sh download.sh


Внимание: каждая часть датасета весит 30GB (весь датасет 270GB).
Как только все части датасета загружены их нужно смерджить в один архив:

cat vox2_dev* > vox2_mp4.zip


Изменим путь до папки mp4 с видео для обучения в файле train.py (строка 21):

path_to_mp4 = '../../Data/vox2_mp4/dev/mp4'dataset = VidDataSet(K=8, path_to_mp4 = path_to_mp4, device=device)


Сейчас запустим скрипт train.py

python train.py


Он выведет в терминал следующее

Initiating new checkpoint......DoneDownloading the face detection CNN. Please wait...Downloading the Face Alignment Network(FAN). Please wait...


На этом все. Можно оживить любые фото, в том числе фото исторических личностей и картины (н-р, Мону Лизу). Успехов вам в оживлении фото!
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru