Трудно быть Коротаевым
494 subscribers
81 photos
98 videos
181 links
🎨 Генеративное искусство, сложные алгоритмы визуализации
🔍 Разбор графики в играх и как это работает,
🎮 Свежие проекты из мира креативного кодинга
😎 Сообщества и конференции о которых стоит знать.

Автор: @lekzd
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
GitHub как анамнез: кардиограмма жизни разработчика

https://codepen.io/lekzd/pen/wBaZbwV
🔥162💘1
This media is not supported in your browser
VIEW IN TELEGRAM
10 PRINT на JS

Повторил знаменитую программу "10 PRINT" на BASIC из этого поста на JS:

Норм? или можете короче сделать?
[...Array(n=10187)].reduce(s=>s+String.fromCharCode(Math.random()<.5?n:n+2),'')


UPD:
[...Array(1e4)].reduce(s=>s+(Math.random()<.5?'⟋':'⟍'),'')

😀

UPD2: Спасибо @gopard за идеи:
s='╲╱';while(!s[1e4])s+=s[Math.random()*2|0]


UPD3: @qod3r
for(s='╲╱';!s[1e4];)s+=s[Math.random()*2|0]


сможете короче?
🔥14👍32💘2
Разбор однострочника на JS

Сутки назад, в этом посте, мы соревновались с читателями кто напишет самый короткий вариант знаменитого однострочника "10 PRINT" но на JS. Вот он:

for(s='╲╱';!s[1e4];)s+=s[Math.random()*2|0]


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

🔥 ВНИМАНИЕ: size-coding это просто творчество, не стоит перенимать практики описанные ниже в коде который должны поддерживать другие люди) 🔥

1. for (s='╲╱';!s[1e4];)s+=s[Math.random()*2|0]

Цикл for оказался наиболее экономным, по знакам:
Array(1e4) который сильно короче просто делает массив из undefined, проблема что с ним не работает ни .map() на .reduce() и нужно в начале использовать .fill(1) что добавляет еще 7 знаков
while просто длиннее =)

—————-

2. for( s='╲╱' ;!s[1e4];)s+=s[Math.random()*2|0]

Первым блоком кода сразу записываем две косые черты в переменную, чтобы использовать их как словарь в будущем

—————-

3. for(s='╲╱'; !s[1e4] ;)s+=s[Math.random()*2|0]

1e4 это короткая запись для числа 10000, экономим 2 знака, уже хорошо

Далее идет блок проверки условия выхода из цикла и тут используется самая короткая запись аналогичная s.length < 1e4, но сильно короче: просто проверяем что 10000-й элемент еще не задан

—————-

4. for(s='╲╱';!s[1e4];) s+= s[Math.random()*2|0]

Так как результатом работы скрипта является строка конкатенируем ее самым коротким способом из всех возможных

—————-

5. for(s='╲╱';!s[1e4];)s+= s[Math.random()*2|0]

Выбираем 0 или 1 символ из результирующей строки. Главная сложность здесь впихнуть довольно длинное выражение Math.random() и превратить его в 1 или 0. Здесь на помощь приходит пара трюков:
— умножаем его на 2 чтобы получить значения от 0 до 2 (но всегда меньше 2)
— откидываем дробную часть используя |0 (побиовый оператор ИЛИ, сравнивает соответствующие биты двух операндов и возвращает 1 в битовой позиции, если хотя бы один из соответствующих битов в операндах равен 1. В противном случае возвращается 0)

💡 Почему это круто?

— Лаконичность: Вся логика умещается в 43 символа!
— Элегантность: Используем особенности JS (научная нотация, побитовые операции).
— Ностальгия: Современный взгляд на классику программирования.
6👍1🤔1💘1
Media is too big
VIEW IN TELEGRAM
Сделал отражения на воде

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

— В смысле это работает в браузере? Там стримминг что ли? Это же стримминг да?

😀
🔥132💘1
Graphite — новый графический бекенд

Что? какой еще бекенд?

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


А раньше что было?

Ganesh! Бекенд который использовал ANGLE! Если понятнее:

— Чтобы что-то нарисовать Chrome использует Skia, библиотеку, которая все рисует.

— Изначально Skia использовала программную растеризацию (CPU), но с ростом сложности веб-страниц (анимации, сложные эффекты) этого стало недостаточно.

— Ganesh добавил поддержку аппаратного ускорения через OpenGL, что значительно повысило производительность.

— OpenGL устаревает и плохо поддерживается на некоторых платформах (например, Windows использует Direct3D, а macOS — Metal).

— Ganesh изначально работал через OpenGL, но Chrome не мог напрямую полагаться на него из-за проблем с совместимостью.

— Но появился ANGLE. Без него пришлось бы писать отдельные реализации Ganesh под каждый графический API, что сложно и неэффективно.

—————

🤬 Так зачем новый бекенд если они разобрались там уже?

Если кратко — скорость, засчет многопоточности. Graphite вместо ANGLE использует Dawn, который является кроссплатформенной имплементацией WebGPU, который лучше параллелится на разные потоки.

Короче теперь ПОЛНЫЙ ответ на знаменитый вопрос с собеседований "что происходит от ввода адреса до пикселей на экране" стал еще сложнее. 😀

Оригинальная статья: https://blog.chromium.org/2025/07/introducing-skia-graphite-chromes.html
🤔8👍4💘1
This media is not supported in your browser
VIEW IN TELEGRAM
Видео монтаж на веб-технологиях

Не без удивления узнал, что автор канала Onigiri использует веб-технологии для создания графики для видео. Там где стандартом давно является After Effects (22.9$/мес), появляется новый игрок: JavaScript (15 бессонных ночей/мес).

Однажды Кирилл рассказывал доклад про монтаж видеороликов используя браузер. Там он объяснял идею, которая выглядело весьма перспективно. А раз до одной идеи не договариваясь додумались как минимум двое, может она начнет новый тренд?

Кстати, визуализация с видео из поста сделана при помощи техники Ray marching, так как она лучше всего подходит для построения фигур из математических формул. Само видео с кучей других визуализаций, да еще и по-русски тут: https://www.youtube.com/watch?v=DzLKsbY1idg
🔥102🤔2💘1
This media is not supported in your browser
VIEW IN TELEGRAM
Теперь мой генарт еще и в игре

Не уверен что будет в таком виде, но посмотрим. Огромное спасибо Ване, который сделал возможность писать шейдеры на TypeScript, отчего их можно компилировать как для WebGL так и WebGPU.
🔥21😈3💘3
This media is not supported in your browser
VIEW IN TELEGRAM
Почему код шейдеров сложный, или Заговор хранителей GLSL

1. Числа — это не числа, а целые миры


В обычном коде float x = 0.5; — это просто число. В шейдерах это:

— 0.5 для одного пикселя,
— -42.0 для другого,
— NaN для третьего (потому что почему бы и нет).

А если переменная зависит от времени, то поздравляю: теперь ты должен держать в голове 4D-пространство. Представь, что пытаешься объяснить коту, почему мячик, который он видит, на самом деле — это волна в пространстве-времени. Кот не поймёт. И ты тоже.

Весело? А ведь именно так и надо размышлять чтобы сделать отражения, как я показывал недавно.

2. Оптимизация, или "Ты что, делишь? Ты смеешь делить?!"

Если в обычном программировании деление — это просто /, то в шейдерах это красная тряпка для быка.

Умножение на обратное? Да, конечно, мы же не варвары.
Деление? Только если готов объяснить на собеседовании, почему твой шейдер тормозит на Intel HD Graphics 2008 года.
Однажды я использовал деление в тестовом задании. Меня не взяли. Теперь я пишу a * 0.001 вместо a / 1000 даже в блокноте.

3. Циклы и IF — это русская рулетка

— Написал for? Прекрасно, а теперь угадай, развернёт ли его компилятор или оставит как есть.
— Добавил if? Отлично, теперь твой шейдер может работать быстрее… или в 10 раз медленнее, потому что ветвления на GPU — это как игра в кости с Сатаной.

Совет: Если у заказчика видеокарта старше него самого — просто беги. Беги без оглядки.

4. Функции? Какие функции?

В шейдерах нет стека вызовов. Вообще. Это значит:

Хочешь использовать функцию? Инлайнь или умри.
Любишь DRY (Don’t Repeat Yourself)? Забудь. Теперь ты — CTRL+C, CTRL+V с молитвой.
Потому что через месяц, когда придётся менять одну строчку в этом "удобном" шейдере, ты проклянёшь себя за красивую архитектуру.

Вывод

Код шейдеров сложный не потому, что он действительно сложный. А потому что так хочет культ GLSL-жрецов. Они сидят в своих чёрных мантиях, шепчут discard; в полночь и смеются, глядя, как мы пытаемся оптимизировать ветвления.

Но если серьёзно — шейдеры это магия. А магию никогда не бывает просто понять. 🧙‍♂️💻 или нет?

Ссылка на шейдер с видео: https://www.shadertoy.com/view/33VGzW
❤‍🔥123🤪3🔥1💘1
Археология JavaScript, new Date() между прошлым и будущим

Мы думали, что отменили Судный день (Y2K). Ан нет — просто отсрочили его, запрятав в недрах new Date().

Когда-то из-за "проблемы 2000 года" (Y2K) COBOL-разработчики стоили дороже золота. Их вытаскивали из пенсии, чтобы те переводили "98" в "1998"за бешеные деньги. А потом... 2000 год наступил, мир не рухнул, и COBOL снова отправили в музей. Но JavaScript, как истинный археолог, сохранил эту логику на века.


1. "0", "00", "0000" — магия или безумие?
Передаёшь строку в new Date() и попадаешь в лабиринт временных парадоксов:

new Date("0")    // 1 января 2000 (логично? нет)  
new Date("00") // 1 января 2000 (ну ладно...)
new Date("0000") // 1 января 0000 (💀 эпоха Иисуса?)
new Date("000000") // 1 января 2000 (а это уже издевательство)


Вывод: Если цифр не 4 — JS додумывает за вас. "0000"? Серьёзно? Кто-то явно пересмотрел "Назад в будущее".

2. "42" vs "51" — путешествие во времени

new Date("42") // 2042 (будущее! 🚀)  
new Date("51") // 1951 (прошлое! 📻)


Почему?

В 1995 году, когда создавался JS, Y2K-паника была в разгаре.
Чтобы отличать 20XX от 19XX, придумали гениальное правило:

00–49 = 2000–2049
50–99 = 1950–1999


Результат: "51" — это 1951, а "49" — 2049. Потому что "так исторически сложилось".

3. Раз есть правило, давайте его проверим:

new Date("0")  // 1 января 2000
new Date("1") // 1 января 2001
new Date("2") // 1 февраля 2001 🤪
new Date("02") // 1 февраля 2001 😅😅😅
...
new Date("12") // 1 декабря 2001
new Date("13") // Invalid Date, верните мой 2013-й год!
...
new Date("32") // 2032


a few moments later...
new Date("106") // 106 год, римляне завоевали Дакию, осуждаем


Ну, нормально же разговаривали...4 символа, я уже запомнил

Теперь попробуем всунуть лишний ноль
new Date("010") // 2001 🤬🤬🤬


и пунктуацию
new Date("1.4")  // 2001, 4 января
new Date("1/4") // 2001, 4 января
new Date("1>4") // 2001, 4 января, плевать какой знак
new Date("1+4") // Invalid Date, а, нет, тут уже считает за таймзону


Вывод

Date — это машина времени, собранная на коленке в 90-е.

P.S. Если ваш код вдруг сломался 1 января 2050 года — вы теперь знаете, кого винить. 😈

Ну а если зашло, то на https://jsdate.wtf можно еще примеров найти
🔥16❤‍🔥3🤣31💘1
Буду снова выступать со стендапом: в этот раз про то как работается когда у тебя 2 детей)
🤝5💘4😁3
Forwarded from Selectel Team
Они смеялись в лицо выгоранию...

И правильно делали😎

Помимо докладов, на Selectel Day Off мы приготовили несколько зон притяжения — рассказываем про одну из них.

🎤 IT Open Mic — стендап от айтишников для айтишников. Нет, не тот утренний скрам-стендап с командой. Ребята приготовили честные сторителлинги про жизнь и работу в IT, которые отзовутся каждому.

Шуток много не бывает, а до Day Off еще 12 дней! Кидай в комменты любимый мем про работу и ставь реакции лучшим🔥


Подробнее про Selectel Day Off рассказываем в канале Selectel Events — переходи, чтобы узнать больше.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12💘1