Creative Coder
443 subscribers
196 photos
134 videos
4 files
308 links
Креативна розробка вебу з ароматом смаженої москальні. Передовий край веб технологій та дизайн ідей, поки є електрика :)

@dre1337
加入频道
Как круто рендерить кукурузку или разбор corn revolution 🌽

По запросу ребят из @promaxdesign решил исследовать рендеринг https://go.pioneer.com/cornrevolution от https://resn.co.nz/. Там действительно есть крутые фишки, но обо всём по порядку 😊

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

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

Фон – два радиальных градиента на SDF с шумом, шум самый обычный
fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123); 

Частицы в расфокусе на самом деле не в расфокусе, а полупрозрачные поинты, форма которых определяется опять же при помощи SDF. Как это делать можно почитать тут – https://thebookofshaders.com/07/. Разрабы прямо в коде шейдера манерно оставили ссылку :) Цвет определяется просто юниформой, а вот прозрачность зависит от 4х факторов – форма (SDF), расстояние, время и юниформа opacity.

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

А потому, что блюр качана делается тоже при растеризации. Это даже не блюр, а просто текстура с альфа каналом, который делает края листов прозрачнее. Кроме того, освещение запечено в 4х текстурах и интерполируется в зависимости от вектора uTextureBlend, который в свою очередь зависит от поворота качана:
    vec4 textureTopLeft = texture2D(uTextures[0], uv);
vec4 textureTopRight = texture2D(uTextures[1], uv);
vec4 textureBottomLeft = texture2D(uTextures[2], uv);
vec4 textureBottomRight = texture2D(uTextures[3], uv);
vec4 outputTop = mix(textureTopLeft, textureTopRight, uTextureBlend.x);
vec4 outputBottom = mix(textureBottomLeft, textureBottomRight, uTextureBlend.x);
finalOutput = mix(outputTop, outputBottom, uTextureBlend.y);
На каждый фрагмент тратится просто 5 чтений текстуры, 3 линейные интерполяции и одно деление для альфы. И всё. Блюр на WebGL тормозит? Нет, Resn про это не слышали. И освещение на высшем уровне без больших затрат на его вычисление. Очень круто 🤘

Текст рисуется MSDF, линии SDF, кружочки — поинты. После предыдущего не так интересно, техники известные, реализация крутая и хорошо проработанная.

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

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

Похожие переходы между сценами вроде описаны тут https://yangx.top/creative_coder/45 но это не точно

Спасибо @eX_gd за найденные ошибки и помощь в их исправлении 💪

Как обычно, возникшие вопросы задавайте в @creativecoders или @webgl_ru. Cheers!

#reference #tutorial
История одного эффекта

Часть 1. Реверс-инжиниринг, интриги, расследования

Несколько недель назад я увидел классную подборку логотипов от Martin Naumann и подумал а что если сделать такое на WebGL и оживить? Выглядит не сложно, будто выдавленный вперёд логотип, отражающий окружение. Задача сводится к построить текстуру с расстоянием до контура (называется это SDF), по SDF определить высоту пикселя, посчитать направление отражения и взять какой-то хитрый градиент собственно для окружения. Ну что же, поехали! За пару вечеров справлюсь (ага, конечно :)

Для начала я сделал кружок прямо в шейдере, поигрался с градиентами и почти сразу получил неплохой результат (видео 2). Градиент вычислялся из двух кольцевых градиентов с линейной интерполяцией между ними в зависимости от высоты нормали, по сути цилиндр. Вдохновившись, я решил повторить эффект на букве D. У неё есть и углы и скруглённая часть, то что нужно для теста. Чтобы сильно не заморачиваться в качестве SDF я использовал outer glow в ФШ, градиент теперь строился в зависимости от положения курсора для интерактивности (видео 3). Ага, тоже прикольно, но как-то уже не то. Ну что же, начало положено, завтра продолжу – решил я и ушёл спать.

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

Довольно быстро накатал генератор таких картинок (4), отдельно внешнее поле, отдельно внутреннее. Заблюрил rg каналы в фш, чтобы не было видно совсем уж ступенек, быстренько адаптировал шейдер и вуаля, картинка 5 готова :D Отсутствие активации - это мой ответ Биллу Гейтсу за чипирование 5g ковида.

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

После вечера раздумий, я переделал градиент ближе к начальному и решил брать какую-то нелинейную функцию от расстояния, чтобы получить собственно ту самую красоту на краях символов. Для того чтобы иметь возможность поиграть с этими функциями я и не генерировал карту нормалей изначально. Считать нормали в шейдере стало резко сложнее, но благо нормаль это перпендикуляр к касательной функции, а касательная функции это её производная. Производные за нас отлично считает WolframAlpha (особенно когда пробуешь взять что-то типа производной expSustainedImpulse). Получилось как-то так:
float slope = 1. - pow(1. - dist, 8.);
float slopeDerivative = 8. * pow(1. - dist, 7.);
if (slopeDerivative > 0.) {
normal = normalize(vec3(direction, 1. / slopeDerivative));
}

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

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

#my #tutorial
Юра Артюх выпустил очень крутое видео как из модельки в блендере сделать 3D web конфигуратор всего в 81 строку кода. Must see!

И вроде я когда-то давно решил для себя не использовать r3f, это оверхед, а всё и так тормозит, но. Когда видишь этот dev experience, эту скорость разработки и эту лаконичность результата, соблазн очень велик. Как долго я бы пилил это на чистой трёхе или OGL? То то же.

И да, из описания репы:

Is it slower than raw threejs?

No. Rendering performance is up to threejs and the GPU. Components participate in the renderloop outside of React, without any additional overhead. React is otherwise very efficient in building and managing component-trees, it could potentially outperform manual/imperative apps at scale.

Такие вот дела. А видео стоит внимания 😉

#tutorial
Fun fact. Если скормить рендереру MSDF текста неправильный конфиг, выходит непонятно что но красивенько :) Пользы правда от этого ноль 🤷‍♂️

Ну и раз речь зашла о рисовании текста в WebGL — предлагаю почитать статью Techniques for Rendering Text with WebGL. Внутри 5 техник вывода текста с примерами и описанием их достоинств и недостатков. Хотя выбор в основном сводится либо к первому методу, либо к последнему.

После прочтения предыдущей статьи можно дополнительно ознакомиться с Kinetic Typography with Three.js. Теперь у вас будет возможность вдохнуть жизнь в любую, даже самую загрустившую надпись 😉

Ну а дальше огромный простор для творчества, достаточно поискать на ютубе kinetic typography. Пусть даже это всё вроде и вышло из трендов, знания и умения — сила :)

#tutorial
Creative Coder
У кого какие идеи как это можно реализовать в браузере?) #inspiraton by Gleb Kuznetsov
У нас очень кайфовое сообщество, вариантов накидали массу 😊

Самый надёжный и очевидный вариант предложил @vovazhuruk — использовать секвенции пререндеренных картинок
Плюсы: просто, красиво, апрувнуто Юрой Артюхом :D
Минусы: загрузка картинок, минимальный интерактив, для изменений нужно всё перерендеривать

Вместо секвенции можно использовать видео, о чём когда-то в нашем чате писал @dergachevm. Он предложил крутое решение проблемы с лагами при перемотке видео в обратную сторону
В теории оно хорошо уменьшает объём загружаемых данных и меньше кушает память браузера

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

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

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

Есть ещё такая вот работа и вроде должно получаться с аппроксимациями, но публичной реализации я не видел
https://www.researchgate.net/publication/220506766_Approximate_Ray-Tracing_on_the_GPU_with_Distance_Impostors
Может на самом деле это и сделано в предыдущем варианте, надо разбираться

@Xander_nome предложил использовать Пекс, хотя изначально такой способ реализовали Lusion на трёхе
По сути это развитие того что было на codrops
Плюсы: можно менять свойства материала, вроде учитывает глубину (но это не точно), интерактивно, производительно, красиво
Минусы: нет внутренних отражений, для кристаллов не пойдёт

И конечно же мой вариант — взять и порейтрейсить всё. Пост я скинул в отложенные вечером, а ночью попробовал. Сам кристалл рейтрейсить довольно просто и быстро, но вот с материалами, окружением и тенями пока беда. Но обкладываться костылями я мастер, так что это ещё не финал 😉
Плюсы: красиво, интерактивно, полная свобода
Минусы: дьявольская сложность, долгая компиляция шейдера, только лоу поли мэши, может тормозить (ещё не ясно, тут как выйдет)

Ну и @maksim_zov предложил сделать это на WebGL, за что ему спасибо :D Он крутой дизайнер если что

Кто не знал, для подобных обсуждений есть чат @creativecoders, вступайте 😊

#reference #tutorial
https://www.youtube.com/watch?v=NCpaaLkmXI8

Ещё не смотрел, но с виду он рассказывает как я делаю эти свои демки :)

Update: он использует реймарчинг вместо рейтрейсинга, что не даёт ему возможности переотражать лучи больше пары раз без превращения в слайдшоу. С рейтрейсингом правда другая проблема — время компиляции шейдера растёт экспоненциально с каждым новым отражением 🤷‍♂️

А остальное всё то же самое, refract + reflect и готово 😉

Во второй части наверняка будет изменять IOR для каждого канала для анаглифа и форму изменит на тессеракт (вроде это он вначале)

В общем, годно, рекомендую к просмотру :)

А вот и вторая часть
https://www.youtube.com/watch?v=0RWaR7zApEo

#tutorial
Новое видео Юры Артюха

Помимо создания симпатичной анимации, Юра рассказал про крутую тулзу для работы с анимациями — Theatre.js. Насколько я понял, она позволяет редактировать анимации с привычным для моушн дизайнеров GUI, что даёт возможность не сильно заморачиваясь делать нетривиальные изинги и ещё и значительно упрощает взаимодействие в команде. Можно отдать сцену дизайнеру, он сам доводит анимацию, возвращает таймлайн, готово. Больше не нужно проводить несколько итераций допиливания / сбора фидбека. И это кайф.

dat.gui на максималках. Я два года ждал такую либу :)

#tutorial #tool
This media is not supported in your browser
VIEW IN TELEGRAM
https://www.youtube.com/watch?v=PjHKcdeRQiY

Відтворення ефекту на https://www.zikd.space/de від Юри Артюха. Заодно показує як модифікувати матеріали тришки, що є дуже потужною технікою, і дозволяє робити дива в браузері не пишучи кілометри реалізацій PBR. Хоча в цьому випадку мабуть можна було взяти геометрію ціліндра замість площини і керувати полем offset текстур.

До речі, нагадую про зручний спосіб дивитись шейдери тришки.

Загалом це крутий, хоч і доволі простий ефект. Було б цікаво поекспериментувати з оживленням типографіки і самої форми — це відкриє величезний простір до кінетичної типографіки наступного рівня. Хто спробує і в кого вийде, напишу його ім'я на снаряді 😉😄

#tutorial #reference
Як швидко і просто зробити тривимірний сайт без знання WebGL

Пропоную вашій увазі чудовий туторіал по spline.design

https://www.youtube.com/watch?v=EJxeMbDTkVI

Виглядає дуже круто! Не стільки завдяки тривимірності, а більше завдяки крутому дизайну ще в фігмі. Хоча в 3D стало тільки краще 😉

Тут можна помацати кінцевий результат

#tutorial
This media is not supported in your browser
VIEW IN TELEGRAM
Міні курс по відтворенню bokoko33.me

https://www.youtube.com/watch?v=rxTb9ys834w

Такий собі скорочений безкоштовний аналог threejs-journey.com. Але щоб отримати готовий код доведеться заплатити аж 5$ :)

У відео ви побачите:
• Моделювання в Blender
• Імпорт в Three.js
• Приклад непоганої організації коду
• Як працювати з хелперами щоб зробити розробку зручнішою
• Використання ScrollTrigger
• Адаптивність
• Анімації
• Деплой сайту на Vercel

#tutorial
Крутий навчальний контент по WebGL від @Konstantin84UKR

https://www.youtube.com/channel/UCdD1kIGUO5m5C31eXLwY30w/playlists

Є окремі плейлісти по WebGL, glsl, WebGPU і навіть плейліст по рейтрейсингу. Він доступно і з іллюстраціями пояснює різні концепції і методи роботи з GPU графікою в вебі, і ці туторіали можуть слугувати чудовим фундаментом для подальшої роботи з студіями рівня Immersive Garden наприклад :)

Звісно, компаніям потрібні швидкі результати з використанням готових бібліотек, але без бази і чіткого розуміння як воно все робе прогресувати до небес буде складно. Тому рекомендую😉

#tutorial
GPU dev tech engineer з AMD розповідає як з нуля робити 3D графіку

https://www.youtube.com/@ukrknowledge

Зараз на цьому каналі виходять відео про базові речі, як от що таке растеризація, як працюють матричні перетворення, кольори та анімації. Та в подальщому Ігор можливо дійде до volumetric effects, SSAO/GTAO, Tiled/Clustered Lighting. І все це українською! Тож буде дуже цікаво, підписуйтесь :)

Також можна глянути його доповідь на GDC 2022 — Hybrid Raytracing with Far Cry 6

Все це не WebGL і не web, але WebGL працює на тій самій базі, тож це корисно знати. До речі, він долучився до нашої спільноти @webgl_ua, і в чаті можна поспілкуватися напряму, тож долучайтесь 😉

#tutorial
Туторіал по Spline для початківців

Авторка розповідає як зробити та інтегрувати 3D візуалізацію за допомогою Spline. І незважаючи на простоту там реалізований прикольний інтерактив :)

https://www.youtube.com/watch?v=x3m1PGEfG5c

#tutorial
На новому стрімі Юра розповідав як відтворити 3D об'єкти, які насправді 2D картинки з https://buttermax.net/. Це захоплюючий сайт, що шикарно виглядає ідеально комбінуючи доволі прості ефекти. Рекомендую :)

https://www.youtube.com/watch?v=yWy_Tr98YDc

#tutorial
Як рендерити траву растеризацією

Непоганий туторіал від Simondev, котрий показує як зробити поля травички спираючись на доповідь розробників Ghost of Tsushima на GDC. Представлені концепції доволі круті і варті того щоб в них розібратися, бо конкретних реалізацій може бути багато. І це все можна робити не лише з травою :)

https://www.youtube.com/watch?v=bp7REZBV4P4

Live demo:
https://simondevyoutube.github.io/Quick_Grass/

Github:
https://github.com/simondevyoutube/Quick_Grass?tab=readme-ov-file

А тим часом в @webgl_ua я показую WIP своєї реалізації, які проблеми виникають на шляху і як їх вирішувати :)

#reference #tutorial