3.png
3.9 MB
Скину и файлами, чтобы тексты были не такими пожеванными. Да, без зума тут не обойтись конечно
🔥4💯1
RGB — это не свойство света. Это свойство вашего глаза
Вчера Дейв поймал это на двух самоцветах: под факелом — близнецы, под другой лампой — разного цвета. Камни не менялись. Менялся только свет. Разберём, что это было.
Откройте color пикер: три ползунка R, G, B — и любой оттенок. Кажется, что цвет так и устроен — три числа. Да? Конечно же нет.
Три числа — это про ваш глаз, а не про мир. В сетчатке три типа колбочек (L, M, S), и каждая сворачивает весь спектр света в одно число — берёт интеграл спектра по своей кривой чувствительности. На входе непрерывный спектр, на выходе три отклика. Глаз сжимает свет до трёх чисел. RGB — просто базис поверх этого сжатия: умное упрощение, а не «реальность».
В примере с камнями. Два РАЗНЫХ спектра под одной лампой дают одинаковые три отклика и выглядят одинаково. Сменили лампу — отклики разошлись, и цвет за ними. Это метамерия: совпал цвет ≠ совпал спектр.
Важно понимать что означают эти три числа: цвет это не точка, а целый спектр, свёрнутый глазом в три отклика. У одной «тройки» бесконечно много спектров-прообразов.
При чём тут ваши игры? Бытовая версия «цвет — не три числа» — это color management: линейка vs sRGB, гамут, тонмаппинг, HDR. Ассет, выверенный под один свет, «уезжает» под другим — близкая родня метамерии. RGB при этом остаётся нормальным базисом для большинства игр; смысл не «отказаться», а знать, как всё устроено на самом деле.
Что мы и разберем. Как устроен цвет, зачем в играх нужен спектральный рендеринг, как рендерить красивые самоцветы и другие подводные камни данной темы.
#геймдев #графика #математика #цвет #RGB #метамерия
Вчера Дейв поймал это на двух самоцветах: под факелом — близнецы, под другой лампой — разного цвета. Камни не менялись. Менялся только свет. Разберём, что это было.
Откройте color пикер: три ползунка R, G, B — и любой оттенок. Кажется, что цвет так и устроен — три числа. Да? Конечно же нет.
Три числа — это про ваш глаз, а не про мир. В сетчатке три типа колбочек (L, M, S), и каждая сворачивает весь спектр света в одно число — берёт интеграл спектра по своей кривой чувствительности. На входе непрерывный спектр, на выходе три отклика. Глаз сжимает свет до трёх чисел. RGB — просто базис поверх этого сжатия: умное упрощение, а не «реальность».
В примере с камнями. Два РАЗНЫХ спектра под одной лампой дают одинаковые три отклика и выглядят одинаково. Сменили лампу — отклики разошлись, и цвет за ними. Это метамерия: совпал цвет ≠ совпал спектр.
Важно понимать что означают эти три числа: цвет это не точка, а целый спектр, свёрнутый глазом в три отклика. У одной «тройки» бесконечно много спектров-прообразов.
При чём тут ваши игры? Бытовая версия «цвет — не три числа» — это color management: линейка vs sRGB, гамут, тонмаппинг, HDR. Ассет, выверенный под один свет, «уезжает» под другим — близкая родня метамерии. RGB при этом остаётся нормальным базисом для большинства игр; смысл не «отказаться», а знать, как всё устроено на самом деле.
Что мы и разберем. Как устроен цвет, зачем в играх нужен спектральный рендеринг, как рендерить красивые самоцветы и другие подводные камни данной темы.
#геймдев #графика #математика #цвет #RGB #метамерия
🔥8❤3
Обратная задача: вернуть спектр из трёх чисел
Вчера я рассказал как глаз сворачивает спектр в три числа — и вышло, что у одного цвета таких спектров бесконечно много. Сегодня идём в обратную сторону: из трёх чисел собрать спектр. Вот тут и начинается боль.
Художник красит текстуру в RGB. Никакого спектра на входе нет и не было — так устроена вся индустрия, и это удобно: текстура весит как три канала, а не как десятки чисел на пиксель, инструменты привычные. Умно? Да. Ровно до момента, когда движку нужно посчитать что-то спектральное — дисперсию, цвет под цветным светом, тонкую плёнку. Там на пиксель нужен спектр, а у вас три числа.
Развернуть три числа обратно в спектр — задача недоопределённая. Та же вчерашняя метамерия, только смотрим с другого конца: одному RGB отвечает бесконечно много спектров, и какой из них «настоящий» — узнать неоткуда.
Поэтому задачу не решают, а обходят. Spectral upsampling: по RGB достраивают один правдоподобный спектр — гладкий и физичный (значения в [0,1], без резких пиков), просто чтобы было что отдать в расчёт. Методов хватает: Smits — наивная отправная точка, Meng и Jakob & Hanika — рабочие (последний стоит по умолчанию в PBRT и Mitsuba), а Belcour вообще выдаёт целое семейство спектров под один цвет.
Нужно это далеко не везде. В реалтайме трёх чисел хватает, гнать каждый пиксель в спектр незачем. А вот когда RGB-текстура попадает в физичный расчёт — офлайн-рендер, product-viz, конфигуратор авто, где перламутр должен честно играть под разным светом, — недоопределённость и вылезает. Правильного ответа среди метамеров нет, так что каждый рендерер выбирает свой.
#геймдев #графика #математика #цвет #спектр
Вчера я рассказал как глаз сворачивает спектр в три числа — и вышло, что у одного цвета таких спектров бесконечно много. Сегодня идём в обратную сторону: из трёх чисел собрать спектр. Вот тут и начинается боль.
Художник красит текстуру в RGB. Никакого спектра на входе нет и не было — так устроена вся индустрия, и это удобно: текстура весит как три канала, а не как десятки чисел на пиксель, инструменты привычные. Умно? Да. Ровно до момента, когда движку нужно посчитать что-то спектральное — дисперсию, цвет под цветным светом, тонкую плёнку. Там на пиксель нужен спектр, а у вас три числа.
Развернуть три числа обратно в спектр — задача недоопределённая. Та же вчерашняя метамерия, только смотрим с другого конца: одному RGB отвечает бесконечно много спектров, и какой из них «настоящий» — узнать неоткуда.
Поэтому задачу не решают, а обходят. Spectral upsampling: по RGB достраивают один правдоподобный спектр — гладкий и физичный (значения в [0,1], без резких пиков), просто чтобы было что отдать в расчёт. Методов хватает: Smits — наивная отправная точка, Meng и Jakob & Hanika — рабочие (последний стоит по умолчанию в PBRT и Mitsuba), а Belcour вообще выдаёт целое семейство спектров под один цвет.
Нужно это далеко не везде. В реалтайме трёх чисел хватает, гнать каждый пиксель в спектр незачем. А вот когда RGB-текстура попадает в физичный расчёт — офлайн-рендер, product-viz, конфигуратор авто, где перламутр должен честно играть под разным светом, — недоопределённость и вылезает. Правильного ответа среди метамеров нет, так что каждый рендерер выбирает свой.
#геймдев #графика #математика #цвет #спектр
🔥9
Радуга без единой краски
Мыльный пузырь, лужа бензина, синяя побежалость на нагретой стали — переливаются всеми цветами, хотя пигмента в них ноль. Это тонкая плёнка толщиной с длину волны: свет отражается от верхней и нижней границы, волны складываются и гасятся. Чистая интерференция.
В играх вы это видите чаще, чем думаете: перламутр автокраски, надкрылья жуков, та самая побежалость, бензин в луже, любая «не от мира сего» sci-fi-поверхность. И в Unity HDRP это уже готовая галочка — Iridescence.
Сколько длин волн надо посчитать на пиксель? В лоб — десятки: отражение плёнки бешено осциллирует по спектру. А у вас три числа.
И вот трюк, который почти честный (Belcour & Barla, 2017): дрожащий спектр не семплируют — его аналитически сворачивают сразу в RGB, в замкнутом виде. Мало того, авторы доказали: для диэлектрической плёнки (пузырь, масло) результат совпадает с честным спектральным расчётом. Не «похоже» — совпадает. Редкий случай, когда упрощение почти не врёт.
Почти. Спотыкается он на металлах. У меди показатель преломления резко пляшет по спектру, и предынтеграл начинает мазать: оттенок и насыщенность уезжают.
В пятницу — почему плёнка вообще осциллирует, как её сворачивают в три числа и где щёлкает медь. С интерактивным side-by-side.
#геймдев #графика #математика #цвет #иридесценция #шейдеры
Мыльный пузырь, лужа бензина, синяя побежалость на нагретой стали — переливаются всеми цветами, хотя пигмента в них ноль. Это тонкая плёнка толщиной с длину волны: свет отражается от верхней и нижней границы, волны складываются и гасятся. Чистая интерференция.
В играх вы это видите чаще, чем думаете: перламутр автокраски, надкрылья жуков, та самая побежалость, бензин в луже, любая «не от мира сего» sci-fi-поверхность. И в Unity HDRP это уже готовая галочка — Iridescence.
Сколько длин волн надо посчитать на пиксель? В лоб — десятки: отражение плёнки бешено осциллирует по спектру. А у вас три числа.
И вот трюк, который почти честный (Belcour & Barla, 2017): дрожащий спектр не семплируют — его аналитически сворачивают сразу в RGB, в замкнутом виде. Мало того, авторы доказали: для диэлектрической плёнки (пузырь, масло) результат совпадает с честным спектральным расчётом. Не «похоже» — совпадает. Редкий случай, когда упрощение почти не врёт.
Почти. Спотыкается он на металлах. У меди показатель преломления резко пляшет по спектру, и предынтеграл начинает мазать: оттенок и насыщенность уезжают.
В пятницу — почему плёнка вообще осциллирует, как её сворачивают в три числа и где щёлкает медь. С интерактивным side-by-side.
#геймдев #графика #математика #цвет #иридесценция #шейдеры
🔥9
«Огонь» бриллианта — это не блеск камня
Вы наверняка видели, как бриллиант в кадре вдруг рассыпает спектр по граням. И почти наверняка — хроматическую аберрацию по краям картинки: красный уехал в одну сторону, синий в другую. Выглядит дорого. На деле — почти бесплатно.
Трюк индустрии простой. Берём текстуру и сэмплируем три раза со смещением: R чуть туда, B чуть сюда, G посередине, радиально от центра кадра — вот вам «линза камеры». Либо три луча под тремя фиксированными углами, по одному на канал. Дёшево, один проход, и в массе сцен глаз считывает это как оптику объектива и не сверяет с физикой. Так что приём работает — почти всегда.
Почти. Ломается на крупном плане огранённого прозрачного объекта: бриллиант, призма, стопка стекла, магический кристалл — всё, где луч гуляет внутри. Камень переотражается несколько раз (полное внутреннее отражение), и спектр должен размазываться на КАЖДОМ преломлении. А фейк разделил каналы один раз — и тащит это разделение неизменным. Накопления нет, спектр выходит плоским и не зависит от геометрии огранки. Тут глаз ловит подделку мгновенно.
Где это вылезает в играх? Хром. аберрация постом по краям кадра, лёгкий спектр на гранях дальнего самоцвета — никто не идёт сверять это с физикой, и трюка хватает. Сыпется он там, где сошлись крупный план И множественные преломления: hero-камень в инвентаре, бриллиант в кат-сцене, тот самый сюжетный макгаффин-кристалл. Если «огонь» камня не пляшет по огранке, а едет вместе с экраном — это он и выдал себя.
Глубже — то, что сдвиг каналов выкинул: дисперсия живёт не в пикселе, а на пути луча. Показатель преломления зависит от длины волны — n(λ). Синий преломляется сильнее красного, угол по закону Снелла свой для каждой λ, поэтому спектр и веерится. Но только когда трассируешь сам путь, а не двигаешь каналы в экранном пространстве.
В пятницу разберём руками: фейковый сдвиг каналов против честного λ-raymarch на одном бриллианте. С формулами и демкой, где режимы переключаются вживую.
#геймдев #графика #математика #цвет #дисперсия #призма #шейдеры
Вы наверняка видели, как бриллиант в кадре вдруг рассыпает спектр по граням. И почти наверняка — хроматическую аберрацию по краям картинки: красный уехал в одну сторону, синий в другую. Выглядит дорого. На деле — почти бесплатно.
Трюк индустрии простой. Берём текстуру и сэмплируем три раза со смещением: R чуть туда, B чуть сюда, G посередине, радиально от центра кадра — вот вам «линза камеры». Либо три луча под тремя фиксированными углами, по одному на канал. Дёшево, один проход, и в массе сцен глаз считывает это как оптику объектива и не сверяет с физикой. Так что приём работает — почти всегда.
Почти. Ломается на крупном плане огранённого прозрачного объекта: бриллиант, призма, стопка стекла, магический кристалл — всё, где луч гуляет внутри. Камень переотражается несколько раз (полное внутреннее отражение), и спектр должен размазываться на КАЖДОМ преломлении. А фейк разделил каналы один раз — и тащит это разделение неизменным. Накопления нет, спектр выходит плоским и не зависит от геометрии огранки. Тут глаз ловит подделку мгновенно.
Где это вылезает в играх? Хром. аберрация постом по краям кадра, лёгкий спектр на гранях дальнего самоцвета — никто не идёт сверять это с физикой, и трюка хватает. Сыпется он там, где сошлись крупный план И множественные преломления: hero-камень в инвентаре, бриллиант в кат-сцене, тот самый сюжетный макгаффин-кристалл. Если «огонь» камня не пляшет по огранке, а едет вместе с экраном — это он и выдал себя.
Глубже — то, что сдвиг каналов выкинул: дисперсия живёт не в пикселе, а на пути луча. Показатель преломления зависит от длины волны — n(λ). Синий преломляется сильнее красного, угол по закону Снелла свой для каждой λ, поэтому спектр и веерится. Но только когда трассируешь сам путь, а не двигаешь каналы в экранном пространстве.
В пятницу разберём руками: фейковый сдвиг каналов против честного λ-raymarch на одном бриллианте. С формулами и демкой, где режимы переключаются вживую.
#геймдев #графика #математика #цвет #дисперсия #призма #шейдеры
👍5🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
О цвете в играх по-простому
https://dev-math.ru/articles/rgb-tricks/
Как и планировалось в пятницу новый формат. Всю пугающую математику свернул в спойлеры, чтобы текст читался проще. Без спойлеров получается научно-популярный текст. В спойлерах детали.
Всю неделю в канале мы разбирали, где RGB обманывает — началось с того, что Дейв нашёл два самоцвета: под одной лампой близнецы, под другой — разного цвета. Камни те же, поменялся только свет. Чтож, теперь всё собрано в одну статью, и её можно не только прочитать, но и покрутить руками.
По сути, RGB — это не то, как устроен свет. Это то, как устроен ваш глаз: три типа колбочек сворачивают весь спектр в три числа. Для картинки на экране этого почти всегда хватает. Для физики света — уже нет.
В статье — четыре места, где трёх чисел перестаёт хватать:
— метамерия — два разных спектра дают один цвет, пока не сменишь лампу;
— обратная задача — как вернуть спектр из трёх чисел и почему решений бесконечно много;
— тонкие плёнки — переливы мыльного пузыря и бензина на луже; та самая иридесценция, что в Unity HDRP уже лежит галочкой;
— дисперсия — «огонь» бриллианта, который дешёвый фейк не вытягивает на крупном плане.
И всё это — четыре живые 3D-сцены прямо в браузере: переливающаяся плёнка, бриллиант, рассыпающий спектр по граням, метамерные свотчи под разными лампами.
Зачем это вам? В реалтайме вы всё равно фейкаете — вопрос только в том, насколько качественно. А понимание того, как цвет устроен на самом деле, как раз и подсказывает, как фейкать правильно: что важно сохранить, а чем можно пренебречь.
Не забываем делиться статьёй и ставить🔥 — это помогает развитию канала и моей мотивации писать дальше :)
#геймдев #графика #математика #цвет #дисперсия #призма #шейдеры #геймдев #графика #математика #цвет #RGB #иридесценция #дисперсия
https://dev-math.ru/articles/rgb-tricks/
Как и планировалось в пятницу новый формат. Всю пугающую математику свернул в спойлеры, чтобы текст читался проще. Без спойлеров получается научно-популярный текст. В спойлерах детали.
Всю неделю в канале мы разбирали, где RGB обманывает — началось с того, что Дейв нашёл два самоцвета: под одной лампой близнецы, под другой — разного цвета. Камни те же, поменялся только свет. Чтож, теперь всё собрано в одну статью, и её можно не только прочитать, но и покрутить руками.
По сути, RGB — это не то, как устроен свет. Это то, как устроен ваш глаз: три типа колбочек сворачивают весь спектр в три числа. Для картинки на экране этого почти всегда хватает. Для физики света — уже нет.
В статье — четыре места, где трёх чисел перестаёт хватать:
— метамерия — два разных спектра дают один цвет, пока не сменишь лампу;
— обратная задача — как вернуть спектр из трёх чисел и почему решений бесконечно много;
— тонкие плёнки — переливы мыльного пузыря и бензина на луже; та самая иридесценция, что в Unity HDRP уже лежит галочкой;
— дисперсия — «огонь» бриллианта, который дешёвый фейк не вытягивает на крупном плане.
И всё это — четыре живые 3D-сцены прямо в браузере: переливающаяся плёнка, бриллиант, рассыпающий спектр по граням, метамерные свотчи под разными лампами.
Зачем это вам? В реалтайме вы всё равно фейкаете — вопрос только в том, насколько качественно. А понимание того, как цвет устроен на самом деле, как раз и подсказывает, как фейкать правильно: что важно сохранить, а чем можно пренебречь.
Не забываем делиться статьёй и ставить
#геймдев #графика #математика #цвет #дисперсия #призма #шейдеры #геймдев #графика #математика #цвет #RGB #иридесценция #дисперсия
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9❤3
Неделя 1: четыре дыры зашиты — а карты целиком нет
Дейв догонял Хардкода и рефакторил его костыли один за другим: почему чисел именно три (это про глаз, а не про цвет), почему камни-близнецы разъезжаются под другой лампой, почему тонкая плёнка глитчит и как свернуть её аналитически, почему дисперсию не подделать сдвигом RGB-каналов.
RGB — это техника со своей областью применимости, и Дейв теперь видит, где она кончается. Но Хардкод сбежал в трещину, а Статика только набрала силу: эталона у него пока нет.
На следующей неделе:
— небо: трюк, ставший формулой, — тут RGB честнее некуда;
— флуоресценция: то, чего три числа не умеют в принципе;
— каустики с дисперсией: два фейка сталкиваются;
— финал: спектральный эталон против RGB — и сколько правда стоит в миллисекундах.
Дейв догонял Хардкода и рефакторил его костыли один за другим: почему чисел именно три (это про глаз, а не про цвет), почему камни-близнецы разъезжаются под другой лампой, почему тонкая плёнка глитчит и как свернуть её аналитически, почему дисперсию не подделать сдвигом RGB-каналов.
RGB — это техника со своей областью применимости, и Дейв теперь видит, где она кончается. Но Хардкод сбежал в трещину, а Статика только набрала силу: эталона у него пока нет.
На следующей неделе:
— небо: трюк, ставший формулой, — тут RGB честнее некуда;
— флуоресценция: то, чего три числа не умеют в принципе;
— каустики с дисперсией: два фейка сталкиваются;
— финал: спектральный эталон против RGB — и сколько правда стоит в миллисекундах.
🔥6
Дейв теперь в Рилсах
https://www.instagram.com/reel/DaFostRIAxo/?igsh=OXd4cnM0b2x5cGFx
В сторис я выложу видос, но телега жрет качество, так что советую глянуть в инсте. Я продумал, на мой взгляд, довольно интересный научнопопулярный формат видео, с роликами о прикольных вещах и парадоксах в математике + забавных историй. Как раз самое то для инсты. Быстро, ненапряжно и легко потреблять.
Первый рилс про парадокс Симпсона. Если вдруг не знаете забавную историю про Беркли в 1973 году. Советую глянуть 🙂
UPD: И в шортсах https://youtube.com/shorts/ZQpwg1fqtOY?si=fXMKK0shl23uvkBp
#парадоксСимпсона #статистика #данные
https://www.instagram.com/reel/DaFostRIAxo/?igsh=OXd4cnM0b2x5cGFx
В сторис я выложу видос, но телега жрет качество, так что советую глянуть в инсте. Я продумал, на мой взгляд, довольно интересный научнопопулярный формат видео, с роликами о прикольных вещах и парадоксах в математике + забавных историй. Как раз самое то для инсты. Быстро, ненапряжно и легко потреблять.
Первый рилс про парадокс Симпсона. Если вдруг не знаете забавную историю про Беркли в 1973 году. Советую глянуть 🙂
UPD: И в шортсах https://youtube.com/shorts/ZQpwg1fqtOY?si=fXMKK0shl23uvkBp
#парадоксСимпсона #статистика #данные
YouTube
Парадокс Симпсона и Беркли
Беркли, 1973: цифры кричат «дискриминация женщин», а по факультетам...
🔥3❤1
Как вам новые форматы?
Anonymous Poll
28%
Новый комикс
17%
Тема со спектром и цветом
21%
Видео про Парадокс Сипсона
52%
Посты
79%
Статья
34%
Интерактивы
Самая загадочная строчка кода
https://youtube.com/shorts/m55BTiN-AJc?si=Xgf80LrTeeqmQthv
В коде Quake III есть строчка, а рядом — // what the fuck?. Кто её написал, спорят до сих пор.
Чтобы свет в шутере считался правильно, направление каждого луча надо нормировать — поделить на длину, а это корень. Тысячи делений на корень за кадр, и на железе конца девяностых не тянуло. Кто-то срезал эту дорогую операцию магическим числом 0x5F3759DF и сдвигом битов.
Вся красота в одной идее: биты дробного числа — это почти его логарифм. Поэтому обратный корень считается почти даром — пара действий над битами и один шаг Ньютона на уточнение. Невидимая математика, которая держала фпс в норме.
Автора так и не нашли. Не Кармак — следы ведут к Гэри Таролли и Грегу Уолшу, но в самой id Software не признался никто.
https://youtube.com/shorts/m55BTiN-AJc?si=Xgf80LrTeeqmQthv
В коде Quake III есть строчка, а рядом — // what the fuck?. Кто её написал, спорят до сих пор.
Чтобы свет в шутере считался правильно, направление каждого луча надо нормировать — поделить на длину, а это корень. Тысячи делений на корень за кадр, и на железе конца девяностых не тянуло. Кто-то срезал эту дорогую операцию магическим числом 0x5F3759DF и сдвигом битов.
Вся красота в одной идее: биты дробного числа — это почти его логарифм. Поэтому обратный корень считается почти даром — пара действий над битами и один шаг Ньютона на уточнение. Невидимая математика, которая держала фпс в норме.
Автора так и не нашли. Не Кармак — следы ведут к Гэри Таролли и Грегу Уолшу, но в самой id Software не признался никто.
YouTube
Самая загадочная строчка кода
В коде Quake III есть строчка, а рядом — // what the fuck?. Кто её ...
🔥10👎1
Художник рисует гладкое небо, а разработчик видит полосы
Дейв вывел в свой мир закатное небо — мягкий переход от оранжевого к синему. А на мониторе по небу пошли полосы. Картинку он не трогал. Поменялось только то, как её упаковали в биты. Разберём, что это.
Откройте любой редактор, залейте плавным градиентом от чёрного к серому, растяните на весь экран. Гладко? Кажется, что да. Но на больших плавных площадях или при импорте глаз вдруг ловит вертикальные полосы. Откуда они, если в текстуре непрерывный переход?
Дело в том, что цвет в кадре хранят побайтно: 8 бит на канал — это 2⁸ = 256 уровней яркости, и между соседними нет ничего, и это без сжатия. Непрерывный градиент квантуется: длинный плавный участок ложится на одну и ту же ступеньку, потом резко прыгает на следующую. Получаются плоские полосы постоянного цвета со швом между ними. Это и есть бандинг (banding) — видимые ступени-полосы на месте плавного градиента, когда уровней яркости не хватает на гладкий переход.
И тут подключается зрение. На границе двух почти одинаковых тонов оно само добавляет контраст — это полосы Маха, эффект латерального торможения в сетчатке. Разница между ступеньками 1/255, физически почти ноль, а кайму по шву вы видите ясно. Глаз не меряет яркость абсолютно, он меряет перепады (закон Вебера) — и ровно на швах квантования перепад вылезает.
В пятницу — почему именно 8 бит, и три способа убрать полосы.
#геймдев #графика #математика #бандинг #квантование #гамма
Дейв вывел в свой мир закатное небо — мягкий переход от оранжевого к синему. А на мониторе по небу пошли полосы. Картинку он не трогал. Поменялось только то, как её упаковали в биты. Разберём, что это.
Откройте любой редактор, залейте плавным градиентом от чёрного к серому, растяните на весь экран. Гладко? Кажется, что да. Но на больших плавных площадях или при импорте глаз вдруг ловит вертикальные полосы. Откуда они, если в текстуре непрерывный переход?
Дело в том, что цвет в кадре хранят побайтно: 8 бит на канал — это 2⁸ = 256 уровней яркости, и между соседними нет ничего, и это без сжатия. Непрерывный градиент квантуется: длинный плавный участок ложится на одну и ту же ступеньку, потом резко прыгает на следующую. Получаются плоские полосы постоянного цвета со швом между ними. Это и есть бандинг (banding) — видимые ступени-полосы на месте плавного градиента, когда уровней яркости не хватает на гладкий переход.
И тут подключается зрение. На границе двух почти одинаковых тонов оно само добавляет контраст — это полосы Маха, эффект латерального торможения в сетчатке. Разница между ступеньками 1/255, физически почти ноль, а кайму по шву вы видите ясно. Глаз не меряет яркость абсолютно, он меряет перепады (закон Вебера) — и ровно на швах квантования перепад вылезает.
В пятницу — почему именно 8 бит, и три способа убрать полосы.
#геймдев #графика #математика #бандинг #квантование #гамма
🔥8
Чтобы убрать полосы, в картинку нарочно подмешивают шум
Идея дизеринга обратная интуиции. Дизеринг (dithering) — это точно отмеренный шум, который подмешивают к цвету перед тем, как округлить его до ближайшей из 256 ступенек. Там, где раньше длинный участок ложился на одну ступеньку, теперь часть пикселей перескакивает на соседнюю — вперемешку. Вместо плоской полосы со швом — мелкая крупа из двух уровней. Глаз усредняет её обратно в плавный переход, которого в битах уже нет.
Но шум шуму рознь. Закинуть Random.Range — белый шум — и картинка реально станет грязной: зерно лезет в глаза. Ordered-дизер (матрица Байера) дёшев, но оставляет регулярную сетку-крест. А синий шум (blue noise) и распространение ошибки (Флойд–Стейнберг) кладут зерно так, что глаз его почти не вычленяет: энергия шума уходит в высокие частоты, к которым зрение нечувствительно. Поэтому современный движок дизерит синим шумом.
И это не только про градиенты. Тот же приём — dither-fade: пунктирная прозрачность для плавного LOD-перехода, волос, волюметрики, мягких теней, и вывод 10-битного кадра в 8 бит без полос.
В пятницу разложим, какой дизер куда и почему синий шум победил.
#геймдев #графика #математика #дизеринг #bluenoise #шейдеры
Идея дизеринга обратная интуиции. Дизеринг (dithering) — это точно отмеренный шум, который подмешивают к цвету перед тем, как округлить его до ближайшей из 256 ступенек. Там, где раньше длинный участок ложился на одну ступеньку, теперь часть пикселей перескакивает на соседнюю — вперемешку. Вместо плоской полосы со швом — мелкая крупа из двух уровней. Глаз усредняет её обратно в плавный переход, которого в битах уже нет.
Но шум шуму рознь. Закинуть Random.Range — белый шум — и картинка реально станет грязной: зерно лезет в глаза. Ordered-дизер (матрица Байера) дёшев, но оставляет регулярную сетку-крест. А синий шум (blue noise) и распространение ошибки (Флойд–Стейнберг) кладут зерно так, что глаз его почти не вычленяет: энергия шума уходит в высокие частоты, к которым зрение нечувствительно. Поэтому современный движок дизерит синим шумом.
И это не только про градиенты. Тот же приём — dither-fade: пунктирная прозрачность для плавного LOD-перехода, волос, волюметрики, мягких теней, и вывод 10-битного кадра в 8 бит без полос.
В пятницу разложим, какой дизер куда и почему синий шум победил.
#геймдев #графика #математика #дизеринг #bluenoise #шейдеры
🔥10
В тёмных сценах кончаются биты — отсюда и грязь
Глаз устроен нелинейно. Разницу между почти-чёрным и чуть-светлее он видит резко; такую же разницу в ярких цветах почти не замечает — это Вебер–Фехнер. Если раскидать 256 уровней равномерно по яркости, в тенях шаг окажется слишком крупным, и глаз увидит банды, а в ярких участках будет с избытком, и они пропадут зря.
Поэтому яркость хранят не линейно. Гамма-коррекция (gamma) — это степенная кривая, по которой кодируют цвет: она отдаёт больше тёмному, где глаз придирчив, и меньше светлому. Стандарт — sRGB, кривая порядка 2.2. Те же 8 бит растягиваются под восприятие, и 256 уровней хватает на гладкую тень. Приём умный.
А «грязь в тенях» — что это физически? Две вещи разом. Первая — банды: даже с гаммой 8 бит в глубоких тенях не хватает, на тёмное приходится горстка бит, и оно идёт ступеньками. Глаз ловит это именно в темноте — в полумраке зрачок раскрывается, и к перепадам в тенях зрение придирчивее всего. Вторая — муть: если считать свет в неправильном пространстве, тёмные тона разъезжаются по оттенку и грязнятся.
В пятницу — что значит «считать в линейном, а кодировать в sRGB», и почему это меняет всё.
#геймдев #графика #математика #гамма #sRGB #linearworkflow
Глаз устроен нелинейно. Разницу между почти-чёрным и чуть-светлее он видит резко; такую же разницу в ярких цветах почти не замечает — это Вебер–Фехнер. Если раскидать 256 уровней равномерно по яркости, в тенях шаг окажется слишком крупным, и глаз увидит банды, а в ярких участках будет с избытком, и они пропадут зря.
Поэтому яркость хранят не линейно. Гамма-коррекция (gamma) — это степенная кривая, по которой кодируют цвет: она отдаёт больше тёмному, где глаз придирчив, и меньше светлому. Стандарт — sRGB, кривая порядка 2.2. Те же 8 бит растягиваются под восприятие, и 256 уровней хватает на гладкую тень. Приём умный.
А «грязь в тенях» — что это физически? Две вещи разом. Первая — банды: даже с гаммой 8 бит в глубоких тенях не хватает, на тёмное приходится горстка бит, и оно идёт ступеньками. Глаз ловит это именно в темноте — в полумраке зрачок раскрывается, и к перепадам в тенях зрение придирчивее всего. Вторая — муть: если считать свет в неправильном пространстве, тёмные тона разъезжаются по оттенку и грязнятся.
В пятницу — что значит «считать в линейном, а кодировать в sRGB», и почему это меняет всё.
#геймдев #графика #математика #гамма #sRGB #linearworkflow
👍6❤1
Среднее двух цветов темнее, чем должно быть
Наложите полупрозрачный туман на сцену или сожмите текстуру в мип — и по краям, на контрастных границах, поползёт грязная тёмная окантовка. Те же тёмные ореолы вылезают на швах освещения. Картинка будто пачкается сама.
Причина — в том, что почти всё считается прямо в sRGB-кодированных числах. Движок, старый шейдер, да и Photoshop по умолчанию берут два пикселя и усредняют их значения. Но значение — это точка на гамма-кривой, а не количество света. Среднее двух значений не равно значению средней яркости — оно всегда уезжает в тёмное. Отсюда тёмные каймы при альфа-блендинге, мутные швы на мипмапах и даунсэмпле, грязь на краях после сглаживания.
Свет складывается линейно — фотоны просто суммируются. Значит, и считать цвет надо в линейном. Линейный workflow (linear space) — это decode → математика → encode: раскодировал sRGB в линейное, сложил-перемножил-осветил, и только на выводе закодировал обратно в sRGB. Тогда каймы исчезают, а 50% серого — это и правда половина света.
В Unity это галочка Color Space → Linear. И тут важное: линейный режим — не «без гаммы». Гамма остаётся на хранении текстур и на выводе кадра, линейной делается только математика между ними. Гамма и линейное не спорят — это две стадии одного конвейера.
И сюда же стыкуется дизер из вторника: разбивать полосы шумом нужно тоже в правильном месте конвейера — на финальном кодировании в 8 бит, иначе зерно ляжет криво.
#геймдев #графика #математика #linearworkflow #гамма #шейдеры
Наложите полупрозрачный туман на сцену или сожмите текстуру в мип — и по краям, на контрастных границах, поползёт грязная тёмная окантовка. Те же тёмные ореолы вылезают на швах освещения. Картинка будто пачкается сама.
Причина — в том, что почти всё считается прямо в sRGB-кодированных числах. Движок, старый шейдер, да и Photoshop по умолчанию берут два пикселя и усредняют их значения. Но значение — это точка на гамма-кривой, а не количество света. Среднее двух значений не равно значению средней яркости — оно всегда уезжает в тёмное. Отсюда тёмные каймы при альфа-блендинге, мутные швы на мипмапах и даунсэмпле, грязь на краях после сглаживания.
Свет складывается линейно — фотоны просто суммируются. Значит, и считать цвет надо в линейном. Линейный workflow (linear space) — это decode → математика → encode: раскодировал sRGB в линейное, сложил-перемножил-осветил, и только на выводе закодировал обратно в sRGB. Тогда каймы исчезают, а 50% серого — это и правда половина света.
В Unity это галочка Color Space → Linear. И тут важное: линейный режим — не «без гаммы». Гамма остаётся на хранении текстур и на выводе кадра, линейной делается только математика между ними. Гамма и линейное не спорят — это две стадии одного конвейера.
И сюда же стыкуется дизер из вторника: разбивать полосы шумом нужно тоже в правильном месте конвейера — на финальном кодировании в 8 бит, иначе зерно ляжет криво.
#геймдев #графика #математика #linearworkflow #гамма #шейдеры
🔥5
Дизеринг и гамма-коррекция: почему градиенты «бандятся» и откуда грязь в тёмных сценах
https://dev-math.ru/articles/dithering/
Люблю писать такие статьи. Когда я начинал заниматься что графикой, что трекингом, меня очень часто больше всего увлекало на сколько это мир физических ограничений. Нюансы вывода изображения на экран. Нюансы человеческого зрения и тому подобное. Параллельно изучая такие технические моменты ещё и узнаешь, а как что в этом мире работает. И это то, чем меня увлекла когда-то клиентская разработка в отличии от бекенда. Помимо мнгновенного результата действий, то что ты не живешь в чистой абстракции, а сталкиваешься с нюансами практического мира.
Итак. Мы разбирали по кускам тему всю неделю. Теперь полная статья с разбором, интерактивами и так далее. Бандинг, дизеринг, как работает гамма-коррекция, что такое линейное цветовое пространство и зачем оно надо (да и попутно объясняется зачем была нужна гамма).
На сайте произошел большой редизайн. Светлая тема мне нравится наверное чуть больше. Но в основном так как я решил делать игру во вселенной своих комиксов и рилсов. Позже анонс будет размещён на сайте по игре (думаю я управлюсь за 4 месяца ну или хотя бы постараюсь). А так репосты и🔥 как всегда приветствуются. Это мотивирует писать статьи и дальше. Ведь кому-то это интересно.
#devmath #графика #квантование #дизеринг #sRGB #linearworkflow
https://dev-math.ru/articles/dithering/
Люблю писать такие статьи. Когда я начинал заниматься что графикой, что трекингом, меня очень часто больше всего увлекало на сколько это мир физических ограничений. Нюансы вывода изображения на экран. Нюансы человеческого зрения и тому подобное. Параллельно изучая такие технические моменты ещё и узнаешь, а как что в этом мире работает. И это то, чем меня увлекла когда-то клиентская разработка в отличии от бекенда. Помимо мнгновенного результата действий, то что ты не живешь в чистой абстракции, а сталкиваешься с нюансами практического мира.
Итак. Мы разбирали по кускам тему всю неделю. Теперь полная статья с разбором, интерактивами и так далее. Бандинг, дизеринг, как работает гамма-коррекция, что такое линейное цветовое пространство и зачем оно надо (да и попутно объясняется зачем была нужна гамма).
На сайте произошел большой редизайн. Светлая тема мне нравится наверное чуть больше. Но в основном так как я решил делать игру во вселенной своих комиксов и рилсов. Позже анонс будет размещён на сайте по игре (думаю я управлюсь за 4 месяца ну или хотя бы постараюсь). А так репосты и
#devmath #графика #квантование #дизеринг #sRGB #linearworkflow
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8
Лоу-поли, а тормозит: кто съел ваш FPS?
Поговорим о дроуколлах. А то про графику мы зашли сразу с дитеринга, давайте пойдёмся по базе. Так сказать с самого начала. Думаю за 2-3 месяца можно рассказать интересно о том, как рендер работает в современном мире в деталях.
Собираете уровень из лоу-поли-пака: деревня, лес, заборы, камни — по паре сотен треугольников на модель. Геометрия копеечная, а кадр проседает. Открываете профайлер и видите странное: видеокарта простаивает, весь кадр съел процессор, а счётчик батчей в статистике рендера ушёл в тысячи. Та же история в другом костюме — клон Minecraft: мир из кубов по 12 треугольников, каждый куб — отдельный объект, и уже десяток чанков кладёт игру. Как так? Ведь треугольников мало и причем тут процессор?
Процессор не рисует — он раздаёт команды. Draw call — это команда «нарисуй вот этот меш вот этим материалом», которую CPU через графический драйвер отправляет видеокарте. И перед каждой такой командой — бумажная работа: собрать состояние (какой шейдер, какие текстуры, какие буферы, как смешивать), драйвер всё это проверит, переведёт на язык GPU и положит в командный буфер. Только после этого видеокарта доберётся до треугольников.
Собственно, ключевое свойство: цена этой бумажной работы от количества треугольников почти не зависит. Это как заказы в интернет-магазине: оформить один заказ на тысячу ручек — пара минут, оформить тысячу заказов по одной ручке — вечер. Товар тот же, вся разница — в накладных расходах на каждый заказ.
Лоу-поли-пак экономит то, что и так ничего не стоит. Миллион треугольников одним вызовом GPU прожуёт легче, чем деревню из тысячи заборов — тысячей вызовов. Поэтому важно следить за числом дроуколлов.
Статья этой недели «Путь одного draw call»: пройдём всю дорогу команды от вызова в коде до пикселей на экране.
#геймдев #графика #математика #gpu #drawcall #оптимизация
Поговорим о дроуколлах. А то про графику мы зашли сразу с дитеринга, давайте пойдёмся по базе. Так сказать с самого начала. Думаю за 2-3 месяца можно рассказать интересно о том, как рендер работает в современном мире в деталях.
Собираете уровень из лоу-поли-пака: деревня, лес, заборы, камни — по паре сотен треугольников на модель. Геометрия копеечная, а кадр проседает. Открываете профайлер и видите странное: видеокарта простаивает, весь кадр съел процессор, а счётчик батчей в статистике рендера ушёл в тысячи. Та же история в другом костюме — клон Minecraft: мир из кубов по 12 треугольников, каждый куб — отдельный объект, и уже десяток чанков кладёт игру. Как так? Ведь треугольников мало и причем тут процессор?
Процессор не рисует — он раздаёт команды. Draw call — это команда «нарисуй вот этот меш вот этим материалом», которую CPU через графический драйвер отправляет видеокарте. И перед каждой такой командой — бумажная работа: собрать состояние (какой шейдер, какие текстуры, какие буферы, как смешивать), драйвер всё это проверит, переведёт на язык GPU и положит в командный буфер. Только после этого видеокарта доберётся до треугольников.
Собственно, ключевое свойство: цена этой бумажной работы от количества треугольников почти не зависит. Это как заказы в интернет-магазине: оформить один заказ на тысячу ручек — пара минут, оформить тысячу заказов по одной ручке — вечер. Товар тот же, вся разница — в накладных расходах на каждый заказ.
Лоу-поли-пак экономит то, что и так ничего не стоит. Миллион треугольников одним вызовом GPU прожуёт легче, чем деревню из тысячи заборов — тысячей вызовов. Поэтому важно следить за числом дроуколлов.
Статья этой недели «Путь одного draw call»: пройдём всю дорогу команды от вызова в коде до пикселей на экране.
#геймдев #графика #математика #gpu #drawcall #оптимизация
🔥19❤5❤🔥1