Создаю новое направление в изобразительном искусстве — программный LLM ART

от автора

Мы посмотрим и на Корбена Далласа и Лилу из фильма «Пятый элемент», на сюжет из фильма «Люди в черном» и другие интересные арты.

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

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

Но это пассивное поведение.

И тут возникает вопрос. А что, если заставить модель проявить себя в активном действии, творческой самореализации? Пока не будем говорить о самых последних версиях GPT-4o и Gemini 2.0 Flash, которые нативно поддерживают непосредственную генерацию изображения по запросу, так же как и текст.

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

То же самое мы можем проделать с LLM, дав инструкцию нарисовать заданный сюжет, а вместо кисти и красок будет код. Например, HTML5 и API canvas.

Насколько хорошо развит канал преобразования внутренних визуальных представлений в программную реализацию и представление на экране?

Некоторое время назад я уже писал статью на аналогичную тему «LLM и ее невозможный ASCII art», в которой обычная LLM создавала изображения в виде ASCII art, но делала это с очень большим трудом за несколько последовательных шагов улучшения.
Я предполагаю, что современные мультимодальные модели должны в разы, если не на порядок лучше рисовать на canvas.

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

Начинаем эксперимент

Deepseek и Qwen не справились.
GPT-4o не справились.
Llama 3.2 90B Vision Instruct не справились.
Gemini-2.0-Flash не справились.
ChatGPT не справились.
OpenAI o1-mini не справились.
Grok-2 не справились.
Claude 3.5 Haiku не справились.

Gemini-2.5-Pro подаёт хорошие надежды и переходит в разряд лидеров.

Но лучшая модель, безусловный лидер, оправдавший мои самые смелые надежды, это оказалась Claude 3.5 sonnet.
Её творчество и будет предметом данной статьи. Модель использовалась без опции доступа в интернет.

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

Первый арт

Промпт:

Напиши HTML-код, который рисует изображение Малдера и Скалли из фильма «Секретные материалы» на canvas размером 1200×600 пикселей. Рисунок создается программно с использованием только нативного JavaScript и Canvas, без внешних библиотек и изображений.

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

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

Поэтому вторым промптом я усовершенствовал Малдера и Скалли.

Корректировка арта.

У нас имеется следующий HTML код, рисующий Малдера и Скалли из фильма «Секретные материалы».(Здесь код функций рисования Малдера и Скалли).
Сделай Малдера и Скалли более реалистичными, детальными и красивыми.

Все картинки кликабельны.

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

В конце концов, и знаменитые художники порой многократно дорисовывали и перерисовывали детали своих картин. Например, Илья Репин дописывал свои картины, выставленные прямо в Третьяковской галерее, а Константин Савицкий дорисовал медведицу и трёх медвежат на картине Ивана Шишкина «Утро в сосновом лесу».

Посмотреть арт в динамике в песочнице. (на страничке нужно выбрать — Yes, proceed to preview).

Здесь, для примера, код функция рисования агента Малдера
function drawMulder() { ctx.save(); ctx.translate(400, 500);  // Цвета для Малдера const skinTone = "#e0c8b0"; const suitColor = "#333340"; const hairColor = "#3a2d1a";  // Ноги (под телом для правильного перекрытия) ctx.fillStyle = suitColor; // Левая нога ctx.beginPath(); ctx.moveTo(-20, -30); ctx.lineTo(-25, 40); ctx.lineTo(-5, 40); ctx.lineTo(-7, -30); ctx.closePath(); ctx.fill();  // Правая нога ctx.beginPath(); ctx.moveTo(7, -30); ctx.lineTo(5, 40); ctx.lineTo(25, 40); ctx.lineTo(20, -30); ctx.closePath(); ctx.fill();  // Обувь ctx.fillStyle = "#111"; // Левый ботинок ctx.beginPath(); ctx.moveTo(-25, 40); ctx.lineTo(-30, 45); ctx.lineTo(-5, 45); ctx.lineTo(-5, 40); ctx.closePath(); ctx.fill();  // Правый ботинок ctx.beginPath(); ctx.moveTo(5, 40); ctx.lineTo(5, 45); ctx.lineTo(30, 45); ctx.lineTo(25, 40); ctx.closePath(); ctx.fill();  // Тело (пиджак) ctx.fillStyle = suitColor; ctx.beginPath(); ctx.moveTo(-5, -110); ctx.lineTo(-22, -100); ctx.lineTo(-24, -30); ctx.lineTo(24, -30); ctx.lineTo(25, -98); ctx.lineTo(5, -110); ctx.closePath(); ctx.fill();  // Белая рубашка и галстук ctx.fillStyle = "#fff"; ctx.beginPath(); ctx.moveTo(-10, -100); ctx.lineTo(-5, -30); ctx.lineTo(5, -30); ctx.lineTo(10, -100); ctx.closePath(); ctx.fill();  // Галстук ctx.fillStyle = "#a32f2f"; ctx.beginPath(); ctx.moveTo(0, -100); ctx.lineTo(-4, -30); ctx.lineTo(0, -35); ctx.lineTo(4, -30); ctx.closePath(); ctx.fill();  // Левая рука ctx.fillStyle = suitColor; ctx.beginPath(); ctx.moveTo(-20, -100); ctx.lineTo(-45, -50); ctx.lineTo(-40, -40); ctx.lineTo(-15, -80); ctx.closePath(); ctx.fill();  // Левая кисть ctx.fillStyle = skinTone; ctx.beginPath(); ctx.moveTo(-45, -50); ctx.lineTo(-50, -35); ctx.lineTo(-40, -35); ctx.lineTo(-40, -40); ctx.closePath(); ctx.fill();  // Правая рука с пистолетом ctx.save(); const armAngle = Math.sin(frameCount * 0.02) * 0.1; ctx.translate(17, -80); ctx.rotate(Math.PI / 4 + armAngle*2);  // Рукав ctx.fillStyle = suitColor; ctx.beginPath(); ctx.moveTo(-10, -18); ctx.lineTo(30, -8); ctx.lineTo(32, 5); ctx.lineTo(-5, -3); ctx.closePath(); ctx.fill();  // Манжет ctx.fillStyle = "#fff"; ctx.beginPath(); ctx.moveTo(25, -6); ctx.lineTo(35, -4); ctx.lineTo(36, 0); ctx.lineTo(26, -2); ctx.closePath(); ctx.fill();  // Кисть правой руки ctx.fillStyle = skinTone; ctx.beginPath(); ctx.moveTo(30, -4); ctx.lineTo(38, -2); ctx.lineTo(40, 3); ctx.lineTo(32, 1); ctx.closePath(); ctx.fill();  // Пистолет ctx.fillStyle = "#111"; // Основная часть пистолета ctx.beginPath(); ctx.moveTo(38, -2); ctx.lineTo(65, 0); ctx.lineTo(65, -5); ctx.lineTo(35, -7); ctx.closePath(); ctx.fill();  // Рукоять пистолета ctx.beginPath(); ctx.moveTo(42, -3); ctx.lineTo(42, 5); ctx.lineTo(48, 5); ctx.lineTo(48, -2); ctx.closePath(); ctx.fill();  // Спусковой крючок ctx.beginPath(); ctx.moveTo(48, 0); ctx.lineTo(50, 2); ctx.lineTo(52, 0); ctx.closePath(); ctx.fill();  ctx.restore();  // Голова ctx.fillStyle = skinTone; ctx.beginPath(); ctx.ellipse(0, -130, 16, 20, 0, 0, Math.PI * 2); ctx.fill();  // Волосы ctx.fillStyle = hairColor; ctx.beginPath(); ctx.moveTo(-20, -150); ctx.quadraticCurveTo(15, -157, 20, -142); ctx.lineTo(-17, -135); ctx.quadraticCurveTo(-10, -100, -25, -130);  ctx.closePath(); ctx.fill();  // Детали лица // Глаза ctx.fillStyle = "#fff"; ctx.beginPath(); ctx.ellipse(-6, -131, 5, 2, 0, 0, Math.PI * 2); ctx.fill();  ctx.beginPath(); ctx.ellipse(8, -131, 5, 2, 0, 0, Math.PI * 2); ctx.fill();  // Зрачки ctx.fillStyle = "#222"; ctx.beginPath(); ctx.ellipse(-6, -131, 2, 2, 0, 0, Math.PI * 2); ctx.fill();  ctx.beginPath(); ctx.ellipse(8, -131, 2, 2, 0, 0, Math.PI * 2); ctx.fill();  // Брови ctx.strokeStyle = hairColor; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.moveTo(-12, -136); ctx.quadraticCurveTo(-6, -139, -2, -136); ctx.stroke();  ctx.beginPath(); ctx.moveTo(13, -136); ctx.quadraticCurveTo(6, -139, 4, -136); ctx.stroke();  // Нос ctx.strokeStyle = "#aa8877"; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(0, -131); ctx.lineTo(0, -123); ctx.lineTo(3, -120); ctx.stroke();  // Рот ctx.beginPath(); ctx.moveTo(-5, -118); ctx.quadraticCurveTo(0, -117, 6, -118); ctx.stroke();  ctx.restore(); } 

Второй арт

Промпт:

Напиши HTML-код, который рисует интересный сюжет из фильма «Люди в черном» на canvas размером 1200×600 пикселей. Рисунок создается программно с использованием только нативного JavaScript и Canvas, без внешних библиотек и изображений.

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

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

Посмотреть арт в динамике в песочнице.

Третий арт

Промпт:

Напиши HTML-код, который рисует Корбена Далласа и Лилу из фильма «Пятый элемент» на canvas размером 1200×600 пикселей. Рисунок создается программно с использованием только нативного JavaScript и Canvas, без внешних библиотек и изображений.

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

Посмотреть арт в динамике в песочнице.

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

Ну и напоследок, раз уж я сравнил эту модель с Леонардо да Винчи, пусть она попробует нарисовать знаменитый рисунок Леонардо «Витрувианский человек».

Модель подошла творчески и решила поглубже войти в образ и в коде применила такие нюансы, как «эффект выцветания по краям», «небольшие трещины пергамента», а также знаменитые высказывания на латыни типа «homo ad quadratum et circulum», но справа налево, как иногда делал сам Леонардо.
Ну и подпись тоже в обратном порядке. Хороший ход.

Посмотреть арт в песочнице.

P.S. Все HTML-файлы с артами можно скачать архивом здесь и посмотреть локально.


ссылка на оригинал статьи https://habr.com/ru/articles/898670/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *