Григорий Дядиченко – Telegram
Григорий Дядиченко
2.82K subscribers
395 photos
160 videos
7 files
1.2K links
Разработчик игр, интерактивных стендов и интерактивной рекламы. Эксперт в области интерактивов и XR.

100+ проектов за 5 лет.

По вопросам сотрудничества писать: @it_bizdev
Реклама в канале: https://vk.cc/cNhGLE
Download Telegram
Компьютерная графика про математические трюки

На самом деле большая часть работы с шейдерами, VFX, светом и т.п. Это всё математические трюки. Часто смотря на какое-то явление при разработке шейдера или чего-то подобного мы стараемся найти упрощённую математику для него. Когда-то давно я писал серию статей по математике в геймдеве, где через примеры пытался показать применения этой самой математики. Вот для скажем статья с функцией плоской волны. Когда понимаешь концепцию того, что значит "считается в каждой вершине" и "в каждом пикселе" параллельно, то проще понимать как передаются туда аргументы, и как их можно использовать в функциях. Допустим в статье по волне можно представить, что в центре меша у нас есть точка (пивот) и аргументом для функции волны является длинна вектора от пивота до конкретной вершины меша (фаза в уравнении) + время действия эффекта

Поэтому для написания прикольных эффектов полезно понимать некоторые концепции из математики. Но тут конечно в математике есть огромная проблема. Так же как и с чтение того же Рихтера. Рихтера в разы проще читать, когда уже что-то понимаешь в разработке и когда понимаешь зачем он тебе нужен. Я люблю периодически смотреть лекции мфти по вышмату. Они лежат в открытом доступе и очень интересные (на них непростительно мало просмотров) Есть по самым разным темам, и без семинаров конечно усваивать материал сложно, но при желании — можно. И проблема всего вышмата, и всех лекций по нему, что я когда-либо видел. Вышмат всегда идёт от теории, а не от примеров. А с примерами было бы учить в разы интереснее.

Скажем вчера в чатике CG мы обсуждали сферические гармоники. И если посмотреть лекции по этой теме в физтехе, то лучше не надо. Если для вас оператор Лапласа, свёртка функций и т.п. магия, смотреть это нет смысла. И там приводится решение с доказательством абстрактных понятий и абстрактных задач. Но совершенно непонятно "А зачем мне это знать?" Хотя скажем вот эта статья это уже объясняет (если пропустить эльфийский для не эльфов, и почитать описания на английском и картинки) По сути привести примеры из астрономии, компьютерной графики и прочему не так долго. Даже не во время лекции, а хотя бы ссылками на "почитать". Скажем перед лекцией, чтобы на лекции было понятно "зачем это"

Просто я не разделяю позиции многих преподавателей, что "это всё неважно, теория объясняет весь спектр применений". Так как зачем самостоятельно повышать входную планку? Я только через 2 года после начала коммерческой разработки смог нормально читать и понимать Рихтера, через 3-4 года чистую архитектуру как просто "понятную брошуру". Так как у меня уже были насмотренность и опыт на практике. И сейчас тоже самое с вузовскими знаниями. У меня была мат. база из-за моей вышки, но по сути я сейчас часто изучаю всё заново, просто в разы быстрее, так как понимаю, как воспринимать эту информацию. В целом математику самостоятельно изучить можно даже стартуя со школьных знаний, сейчас много открытых источников. Но это конечно будет тяжелее, чем в вузе, потому что информация особо не структурирована в плане порядка изучения)
👍6
Клёвый мануал по 2д

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

Вообще я чёт ничего не пишу про 2д, всё про 3д. Надо будет про что-нибудь в 2д написать, даже про тот же VFX. После следующей статьи подумаю про что можно написать в 2д играх :)
👍13
Классная рекомендация по организации 2д анимаций https://youtu.be/nBkiSJ5z-hE Переключать стейты «руками» в разы лучше, чем организовывать граф состояний, когда вам не нужен блендинг и blend tree
👍4
Крутой репозиторий с блюром

https://github.com/PavelDoGreat/Super-Blur — старый репозиторий, но всё ещё прекрасный. Неплохо работает на мобильных устройствах. По сути на одной из его старых версий я когда-то делал свой акрил https://www.youtube.com/watch?v=7CtoEqyu3fI Может кому пригодится :) У автора ещё крутой репозиторий с жидкостной симуляцией на вебгл)
👍4
Григорий Дядиченко pinned Deleted message
Кривые Безье

Чтож, тут тоже мало смысла повторяться, так как есть шикарный ролик. Советую посмотреть. Кривые в целом супер полезная штука очень много для чего, так как благодаря ним помимо того, что описывает Фрея, делается ещё достаточно много разных эффектов в VFX, в процедурной генерации графики и т.п. Кривые Безье по сути частный, удобный и быстрый вид сплайнов. А сплайны уже в свою очередь — это маст хев знание, так как они очень сильно упрощают жизнь в анимациях, в построении уровней и т.п.
👍5🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
— Уже скоро 30, устройся на работу!
— Я и так работаю, мам!

Иногда в продакшене бывает трудно объяснить чем ты занимаешься и что это настоящая работа :)
👍17
Инкремент номера билдов

Номера билдов в мобильные сторы. Задавать их руками это какой-то особенный вид удовольствия, а если настроен CI&CD так вообще странно. Я тут на просторах интернетов нашёл полезный скрипт с с автоматической инкрементацией билдов. Я бы конечно его чутка переписал, но в целом даёт понимание, как на препроцессе билда автоматом инкрементить версию и номер билда. Просто в айос дико бесит, когда ты взял, собрал икскод проект, собрал в нём архив, начинаешь заливать в коннект и оно говорит "обнови версию". И тебе надо заново собирать архив)
👍4
New Input System и XR

Погорячился я с прекрасностью новой InputSystem. Ну хотя ей всего лишь год, а что такое для Unity год? Как бы было бы удивительно, если бы всё работало хорошо из коробки. Но судя по всему никто этой системой особо не пользуется, и я сейчас просто убил 2 часа на абсолютно великолепную задачу. Но тут нужна небольшая предыстория + моё решение может сэкономить вам уйму времени)

Клавиатурный ввод в VR — это одна из основных проблем. Сколько бы клавиатур не делали они неудобные. Ни с точки зрения копирования откуда-либо, ни с точки зрения печати. Ну это просто неудобный инструмент и не сравнится с функциональностью обычной клавиатуры. И по этой причине я очень часто в VR системах делаю оверлей интерфейс куда выносится вся печать, и интерфейс в VR в котором просто "нажми кнопку". Это очень хорошо зарекомендовало себя по UX во всяких профессиональных инструментах и аналитических системах. Есть просто типа админка в видео Overlay UI.

Меня собственно новую инпут систему заставил попробовать OpenXR, так как сейчас на старой системе казалось геморнее пробросить все инпуты и т.п. И проблема в общем-то даже не в самой инпут системе, а в InputSystemUIInputModule. С ней всё окей. Но Unity не были бы Unity, если бы всё работало. И видимо этой системой в целом в XR мало кто пользуется пока, так как в кейсе выше не работает мышь! Это просто фентези! Короче, так как юнитеки подумали наконец-то решить старую проблему видимо, что поинтеры и канвасы в VR не юзают и обычно пишут либо свои инпутсистемы, либо делают на коллайдерах, они решили сразу это сделать. Проблема в небольшой такой детали "Поинтер может быть только один". Поэтому выбирай, либо мышь, либо XR Controller в качестве поинтера. Правда же? Выбирай?

А вот и нет, у тебя нет такой роскоши, как право выбора. Если у тебя в целом включена поддержка XR контроллеров, то мышь не работает. Поставить приоритет (если у тебя нет в VR интерфейса) так же нельзя. То есть хочешь инпут с контроллеров — забудь про мышь, они ведь тебе не могут быть нужны. Типа фиг с ним, что не поддерживается всё и сразу, хотя ограничение немного непонятное. Но то что даже выбрать нельзя — это кайф. И вот на это я потратил 2 часа своей жизни.

Если кому-то нужен workaround рабочий. В плеер сеттинге ставите поддержку и старой, и новой инпут системы. Кидаете на EventSystem скрипт StandaloneInputModule игнорируя "фикс" и сообщение о том, что ничё работать не будет. Так как если в плеер сеттингах включить обе инпут системы, то ивентсистема с мышью работает — профит.
👍1😱1
Всегда интересно смотреть разные VFX Breakdown видео, чтобы "подглядеть" и возможно использовать какие-то подходы и техники в своих проектах https://www.youtube.com/watch?v=GSnRTKswzEc Когда видишь скелет реализованного в целом понятно, как это сделано)
Как я номера распознавал

Математика вещь великая. Есть такая штука, как дистанция или расстояние. Обычно оно воспринимается между координатами, но в целом никто не мешает создавать свои дистанции. Когда-то давно я делал проект, где нужно было распознавать номера автомобилей и сравнивать с тем, что задан в системе. Но неиронная сеть, которой я пользовался возвращала достаточно шумные данные. А мне нужно было при нахождении номера слать нотификацию. И тут я подумал, надо как-то определять, что номера "похожи")

Ввести расстояние удобно чисто по той причине, что можно настраивать "что считается похожим" с точки зрения некоторой точности. Типа возьмём две строки. Если расстояние между ними условные 10 или условные 100, и мы настраиваем какие значения мы принимаем за "правильные". Очевидно, что 100 может получиться менее точным, так как будет группировать в одну больше строк. Вторая причина — удобная визуализация. Распознавания с видео-камеры представляют из себя временной ряд "строка" и кадр. И в данном случае очень удобно можно введя понятие расстояния видеть, как проходило распознавание и по какой "дельте" группировать. Но вернёмся к задаче

Расстояние Левенштейна — достаточно известная штука в компьютерной лингвистике. Определяется, как если сравнивать две строки, какое количество букв нужно поменять, чтобы получить другое слово.
Например kitten → sitting — расстояние 3. Меняем k на s, e в конце на i и добавляем g в конец. Получается 3 операции.
Это было первое, что я попробовал и конечно же оно не работало. Проблема в структуре "шума" нейронки. Левинштейн очень не устойчив к перестановкам символов, что было довольно частой ошибки той нейронки)

Что Левинштейн не подошёл, давайте придумаем своё. Посидев недельку с данными, посмотрев на то, как выглядит ошибка неиронки. Я придумал следующее решение. Нашёл самые часто путающиеся символы, посчитал их количество. Задал им веса таким образом, чтобы сумма любой пары весов не давало какой-то другой вес (простые числа). И дальше просто суммировал символы по весам. Номера case insensitive — так что нужно было сравнивать только символы и числа. Допустим объединив цифры A и H которые неросеть часто путала, задав им вес 1 получалось что номера AA123A и HH123A — это одинаковые номера. Тоже самое с цифрами 3 и 8, то есть AH128H — это тот же самый номер по весу. Это работало лучше, но проблема оставалась. У нас нет расстояния, так как веса из простых чисел дают суммы, которые никак не назовёшь расстоянием) Поэтому это как-то работало, но уточнять смотря на графики не получалось

А что если поместить символы и цифры на круге? Представляем, что мы те же группы символов разместили на единичной окружности, а те которые тоже "путаются", но не так часто, просто постарались поставить соседями на этом круге. А что же является расстоянием. В номерных знаках фиксированное число символов (там есть различия с транспортными номерами, но их проще обработать программно). Поэтому в качестве расстояния мы используем — площадь многоугольника получившегося из точек на этой окружности. И вот это уже работало довольно неплохо)

Возможно компьютерные лингвисты знают решение ещё элегантнее и известное, но я специалист в первую очередь по трекингу и CV в данном случае, так что придумал вот такой велосипед. И вот пример довольно любопытного применения математики, когда просто придумываешь своё "расстояние" между строками. И на самом деле таких применений масса)
Григорий Дядиченко
Как я номера распознавал Математика вещь великая. Есть такая штука, как дистанция или расстояние. Обычно оно воспринимается между координатами, но в целом никто не мешает создавать свои дистанции. Когда-то давно я делал проект, где нужно было распознавать…
Собственно графики этих "расстояний" строк. В начале, и в середине работы. С последним решением я их не сохранил) На втором графике прозрачное — "реальное распознавание", оранжевое — сгруппированная строка. И тут видно, что в целом группировка как-то начала работать, но в конце какие-то очень шумные данные полетели. И круг это победил)
👍2
Прототипирование — это очень круто

Когда-то давно я преподавал в ВШБИ курс прототипирования. Преподавать в целом полезное дело, просто у меня сейчас слишком много дел, чтобы этим заниматься (куча проектов, разработка и запуск нескольких своих продуктов вроде https://whitelabelgames.ru/) Поэтому честно говоря ну не до того. Ещё тут чёт писать и рассказывать :) В общем не суть :)

Когда я готовил курс я перерыл просто тонну материалов по прототипированию и сам прошёл несколько таких курсов. И как же много вещей можно проверить, посмотреть и т.п. прототипом, и как же редко у нас пользуются прототипированием. Это полезно в согласованиях, полезно для понимания того, как будет работать проект, да может быть прикольно в качестве "тимбилдинга". Помню во времена студентом партнёром Microsoft мы из лего, чет собирали. Но в общем собирать бумажные прототипы занятие довольно прикольное. И да, сейчас есть много инструментов прототипирования, можно прототипировать прям в Unity, но игры отлично прототипируются и на бумаге, да и приложения тоже, особенно UI. В разы дешевле напечатать картинки, чтобы подержать в руке "устройство", которого у тебя нет физически. Но почему-то в РФ я чаще всего видел 3 проблемы

Прототипированием не пользуются

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

Прототипы делают супер сложными

Очень часто проблема в прототипировании, что то что называют прототипом вот ещё чуть-чуть докрутить и можно в продакшен. Прототип должен быть сделан максимально "на глаз", и должен быть выкинут

Прототипы развивают

И это самое страшное, и следует из прошлого. Прототип нужен для того, чтобы сделать его максимально быстро и дёшево, и выкинуть. Прототип который делается 2 недели — это не такой частый кейс. Ну то есть это не прототип механики, это системный прототип. Даже я такие делаю под заказ для различных корпораций, где может быть месяц разработки прототипа, но там на продакшен систему нужно 2-3 года и этот "прототип", это чуть ли не MVP или Proof of Concept. Просто крупные компании могут себе позволить за него заплатить и выкинуть его, когда проверят то, что им надо. А вот то, что мы что-то запрототипировали и потом продолжили докручивать, и перенесли в прод — это в среднем очень плохо, и лучше так не делать

Вообще советую всем пройти какой-нить курс по прототипированию (благо в интернете их масса) Потому что это позволяет прокручивать очень много идей, технологий, проектов — очень быстрыми итерациями. Попробовали — выкинули, попробовали — выкинули. Что существенно повышает качество разрабатываемых продуктов или игр. Ну и UX тоже, конечно же есть UX Heatmap, который все кто занимаются интерфейсом наизусть знать должны. Он показывает где эргономично располагать кнопки. Но подержать в руках и потыкать на каком-нить маленьком устройстве, или наоборот огромном, когда самого устройства нет на руках, или аппу деплоить долго, тоже очень полезно. Занимайся я продуктовой разработкой мобильной, у меня бы у дизайна специальный принтер стоял под эти задачи)
👍6
Интересный ролик по GPU анимациям

Так как в SkinnedMeshRenderer не работает батчинг и гпу инстансинг бывает полезно запечь анимации в текстуру и использовать. В ролике как раз объясняется такая техника. Да и в целом всегда полезно помнить такую вещь, что текстура — это просто массив данных, и как по примеру с параллакс маппингом, нормалями и т.п. в ней можно хранить много интересного помимо собственно цвета)
https://www.youtube.com/watch?v=KUuuXowdYyM
🔥4
Откопал старые замечательные картинки, которые мы делали как шутку во времена консалта XD
😁12👍3
Отсутствие информации — это тоже информация

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

Так, а к чему заголовок то? Сегодня поговорим про бинарную сериализацию, и в целом про одну забавную идею, которая много где используется. Разберём для этого классическую задачку. У нас есть массив [0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,2]. Но чтобы задача не была такой сухой представим что это трасса в раннере где:

0 — свободный кусок трассы
1 — это препятствие, которое нужно перепрыгнуть
2 — финиш

Подумаем, как мы можем это сохранить в нашей игре. Допустим нам хочется оптимальности. Первое что приходит в голову (если мы сразу отбросим SO, Json) и т.п. — бинарная сериализация. Конечно этот подход обладает некоторым числом недостатков (поддержка разных версий без стандартизации и т.п.)

Итак, допустим наши числа — это инты. Инт в C# — это Int32, то есть 4 байта. В нашей трассе 15 символов, то есть 60 байт. Но с числами "0", "1" и "2". мы можем сразу взять не тип int, а тип byte. Он весит 1 байт, так что суммарно мы выиграли в 4 раза, то есть до 15 байт. Можно ли ещё что-то сделать?

Во-первых, так нам не нужен финиш в виде отдельного числа, так что отбросим 2. Осталось 14 байт. А вот второе уже будет посложнее. Чуть-чуть изменим кодировку. Байт принимает значения от 0 до 255. Для упрощения мы считаем, что любая трасса начинается с хотя бы одного 0 (по сути в раннере в начало мы всегда можем поставить пустой блок, и это ничего не испортит игроку) И так как у нас всего 2 типа "пустое" и "с препятствием", то мы можем ту же самую трассу вполне записать как

[1, 1, 1, 2, 1, 1, 7] — что уже в типе байт займёт 7 байт вместо 15. Суть такой кодировки к том, что мы знаем что наша трасса начинается с нуля. И знаем что есть только 2 типа. Поэтому каждая цифра массива означает сколько значений следующего типа дальше.

Сначала у нас 1 ноль (то что трасса всегда начинается с нуля важно, чтобы тут не было разночтений)
Потом одна единица
Потом один ноль
Потом две единицы
Потом один ноль
Потом одна единица
И потом семь нулей

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

Допустим пример выше очень полезен при использовании дельта сжатия, так как его идея заключается в том, что данные часто будут состоять из огромного числа нулей, которые нет смысла писать в виде нулей) И это во многом отвечает на вопрос, как пишутся в 4кб игры с текстурами и в 3д. И по сути все эти идеи на более высокий уровень выводит как раз математика)

В классической разработке это всё не так надо, и скорее просто "прикольное знание". Так как если не тормозит, то и не надо оптимизировать. Стандарты медленнее, во многом хуже, но чаще всего более гибкие и поддерживаемые, чем такие оптимизации. Но когда вам нужно "запихать последний мегабайт графики, чтобы влезть в 100мб ограничения стора" или другая задача повышенной сложности, то такие идеи бывают весьма полезны. Даже на уровне идеи, без знания теоретической базы на тему кодов Хаффмана и других частей теории множеств и теории информации
👍19
Изобретение велосипедов

Иногда просто для любопытства я думаю о каких-то задачках и "изобретаю велосипеды". Когда-то меня заинтересовал вопрос "а почему в компьютеры электрические, а не оптические". Сразу скажу, что если я разбираюсь в графике и в математике, то в физике только в тех областях, что мне нужны были по работе. Поэтому чисто на бытовом уровне я подумал: скорость света сейчас в теории — это самая большая скорость, так почему компьютер внутри себя передаёт данные по проводам, а не по световым трубкам по типу оптоволокна. Сразу скажу, ответа я не нашёл, так как нужно было бы сильно углубляться в проблемы задачи. Да и многое, что вы "изобретаете", уже существует. Просто нужно обладать достаточно широкой фундаментальной и теоретической базой, чтобы изобретать менее очевидные велосипеды)

Это не значит, что их не надо изобретать. Это в целом полезно придумывать какие-то решения, пусть они уже даже существуют и лучше. Так как это и возможность узнать, что что-то существует, и возможность просто размять мозги. И возможно иногда действительно придумать что-то новое, или неочевидное применение существующего. И мой пожалуй любимый велосипед, который я придумал — это "изобретение" MIMO. Если коротко размышляя над скоростями передачи и интернетом, я думал. А было бы круто если передавать данные не потоком, а как бы одновременно) Так бы увеличилась скорость передачи, и в целом информация передавалась быстрее (про то, что такое MIMO я тогда конечно не знал) И вот как раз благодаря этому я понял идею MIMO)

Поэтому размышлять и изобретать велосипеды классно. В коммерции я предпочитаю сначала "погуглить" решение задачи, чтобы просто не тратить лишнее время, но на досуге почему бы не поизобретать велосипеды?) Плюс изобретение велосипедов по-моему опыту учит "правильно гуглить", что является чуть ли не 50% работы современного разработчика. В общем изобретать велосипеды весело. Да и когда "сам придумаешь", сразу понимаешь "что ты придумал", пусть оно даже уже есть :)
👍6