fa
Feedback
Математика в Gamedev по-простому

Математика в Gamedev по-простому

رفتن به کانال در Telegram

Как на самом деле работают стрельба, толпа NPC, графика, физика тканей и свет в играх. Разборы на пальцах, рабочий код, интерактивы. dev-math.ru Сотрудничество: @it_bizdev

نمایش بیشتر
529
مشترکین
+124 ساعت
+87 روز
+3130 روز
آرشیو پست ها
Дневник разработчика Сегодня статьи не будет. Она выйдет где-то на выходных. Я последние несколько дней делал другие статьи. Более практические и крутые, но будут они на закрытом портале. Они уже про реальные технологии производства и конкретные техники по опыту создания моей игры. На них ушло много времени, так что статья про свет немного уехала. Но она всё равно выйдет на этой неделе. Получить доступ можно пока только поддержав игру тиром "Рефакторинг" и выше https://dev-math.ru/support/ В статьях сейчас про документ ферст подход, про создание ассетов на примере "тёмного фентези" и о том, как я создавал ассеты для процедурного тиррейна. Кто заинтересуется может поддержать и получить доступ к этим материалам. Там точно так же будет выходить что-то новое и постараюсь держать тем раз в неделю. Спасибо за внимание! #devmath

В Fallout 3 нет ни одного поезда https://youtube.com/shorts/0Dw4ciULxYQ?si=2GqaYJOx-ryyU72f Поездка на метро есть — в дополнении Broken Steel. А поезда нет: движок не умеет катать по миру объект, внутри которого сидит игрок. Он умеет ровно две вещи — водить персонажа и надевать на него предметы. Поэтому вагон сделали одеждой. В файлах он так и лежит: недоступная броня на слот правой руки. Игрок садится — дальше всё делает скрипт. Надевает броню, включает свой пакет камеры и гонит игрока по путям. Снаружи — метро. Внутри — человек, который надел поезд и побежал. Нравится мне тут не костыль, а причина, по которой он не палится. Подмену нельзя заметить в принципе: пока вагон приклеен к игроку, в его системе отсчёта вагон стоит, а движется мир. Ровно корабль Галилея, только с метро. Про этот вагон, кстати, ходит красивая неправда: будто это шляпа, надетая на невидимого NPC, который бежит под миром. Версия пошла с вброса на 4chan. Слот не головной, и надевает вагон сам игрок — это видно в GECK, официальном редакторе Bethesda, куда фанаты и залезли в 2015-м. #геймдев #fallout #devmath #fallout3

Ребята... Мне нужна ваша помощь https://dev-math.ru/support/ Сегодня наверное будет самое сложное для меня. Всегда хочется казаться крутым и что всё получается. Но пора смириться с тем, что рынок на котором я работал последние 7 лет мертв. И с одной стороны это грустно, так как было убито столько времени и сил в развитие своего дела. А с другой это новая возможность. Всем привет. Меня зовут Гриша Дядиченко. Ну про мой карьерный путь вы возможно читали. И вот начинается новая глава. Возможно знаете меня лично. Может мы вместе тусовались на конференциях. Возможно вы были когда-то на моих митапах в Москве. Возможно вы читали мои статьи, посты, пользовались репозиториями. А может мы вместе когда-то работали. И сейчас мне нужна ваша помощь. Я хочу сделать интересную игру. Но думаю моих оставшихся ресурсов не хватит. Эта игра - ностальгическое путешествие по легендарным историям из разработки. По механике это головоломка вдохновлённая инкредибл машинс и другими старыми головоломками. Хочется сделать что-то действительно крутое и интересное. На рынке, где сейчас не всё так просто, особенно с тем какие палки в колеса на нём вставляются всем. Собственно моя просьба. Если вы верите, что я способен сделать что-то интересное. То поделитесь этим постом или ссылкой, если не трудно. Возможно у вас есть какой-то свой блог, знакомые с блогами, чат (только если в чате разрешено такое публиковать, спамить не надо). А если такой проект вам интересен или есть желание просто поддержать мою инициативу, за все статьи что я написал и репозитории что я сделал, да или просто подкинуть монет на мечту старому знакомому, то вообще супер. Хотелось бы как раньше иметь возможность на покупку рекламы в блогах или вроде того. Но сейчас ресурсы исчерпаны. Я всё равно сделаю игру. Просто с поддержкой она может получиться круче, о ней узнает больше людей, и думаю тогда получится сделать что-то действительно крутое. Инфоцыганином мне пока всё ещё не позволяет стать совесть. Так что буду делать игру. В общем для вас это может быть мелочью или парой кликов, а мне вы очень поможете и я буду признателен.

Гладкость сферы вы видите по свету, а не по форме Мысленный эксперимент: возьмите шарик и покрасьте краской, которая поглощае
Гладкость сферы вы видите по свету, а не по форме Мысленный эксперимент: возьмите шарик и покрасьте краской, которая поглощает падающий свет целиком. Что вы увидите? Не чёрный шар — плоское чёрное пятно. Отражать нечего, перетекания из света в тень нет, и шарообразность из картинки просто исчезает. Эксперимент, кстати, не такой уж мысленный. У покрытий вроде Vantablack, забирающих больше 99,9% видимого света, ровно этот эффект и наблюдают: смятая фольга после покраски теряет все складки и читается как дыра в пространстве. Собственно, вот вывод, который дальше объясняет всё остальное: объём вам даёт не геометрия, а то, как по поверхности разложен свет. Плавный градиент яркости мозг читает как кривизну, резкий скачок — как ребро. Убрали свет — остался ровно силуэт. В обратную сторону это работает так же. Посмотрите на шар в любой игре: бок плавно перетекает в тень, поверхность явно гнутая — а поймайте край на фоне неба, там ломаная из отрезков. Полигонов мало, гладким его сделал не меш. В шейдере яркость точки — это одно число: насколько поверхность в ней повёрнута к источнику. Берётся оно из нормали, лежащей в вершине. И нормаль не обязана быть перпендикуляром своего треугольника: усреднили в вершинах нормали соседних граней — свет поехал по плоской грани плавно, и зрение видит шар. Поэтому гладкость выгоднее рисовать, чем моделировать: полигонами её тоже можно догнать, только платить придётся геометрией. Ну а где считать это число — в вершине или в пикселе, куда при этом умеет пропадать блик и почему грани порой видно там, где разница яркости между ними мизерная, — разберём в пятницу. И загадка туда же. Гладкость нормалями подделывается легко: усреднили соседей — и плавно. А как сделать обратное — острое ребро, чтобы две грани куба или две стены комнаты держали каждая свой тон, без перетекания через угол? Как выкручиваются? #геймдев #графика #математика #рендер #свет #gamedev

Почему далёкая текстура мерцает https://dev-math.ru/articles/textures/ Мне очень нравится конечно составлять эти статьи, так
Почему далёкая текстура мерцает https://dev-math.ru/articles/textures/ Мне очень нравится конечно составлять эти статьи, так как помимо понимания компьютерной графики для меня они являются погружением в ностальгическое прошлое. Как всё было придумано и зачем. В статье разберем: - почему тексель — не пиксель и что на самом деле делают nearest и билинейная фильтрация; - откуда берётся мерцание вдали — алиасинг при уменьшении — и как его лечат мипмапы; - почему при взгляде вдоль пола картинка мылится и что с этим делает анизотропная фильтрация; - сколько всё это весит в памяти и как устроено блочное сжатие BCn и ASTC; - и как эти решения складываются в один запрос к сэмплеру. Ставьте 🔥 и делитесь с друзьями, если статья была интересна. В будущем возможно я сошью это в какой-то учебник по компьютерной графике, который уже будет за символическую цену, чтобы желающие могли поддержать автора так сказать. А пока поделиться постом лучшая поддержка. #devmath #графика #математика #рендер #текстуры

Статья немного задерживается, так как автор в ловушке
Статья немного задерживается, так как автор в ловушке

Пол вдали превратился в кашу? Смотрите вдоль пола — и метрах в десяти плитка перестаёт быть плиткой. Не мерцает, не рябит, а
Пол вдали превратился в кашу? Смотрите вдоль пола — и метрах в десяти плитка перестаёт быть плиткой. Не мерцает, не рябит, а ровно и мутно мылит, как будто туда забыли положить текстуру. При этом та же самая текстура на стене прямо перед носом читается прекрасно, и под ногами всё резко. Мылит именно то, что уходит вдаль под острым углом: пол, дорога, длинная стена сбоку. Дальше начинается знакомый заход. Раз мыло — значит мало разрешения. Дорогу поднимают с 1024 до 2048, потом до 4096, память растёт вчетверо на каждый шаг, стриминг начинает захлёбываться на въезде в локацию — а дорога вдали всё такая же мутная. Ловили такое? Собственно, вот в чём дело. Пиксель накрывает на поверхности не точку, а кусок. Когда поверхность стоит к вам лицом, этот кусок — аккуратный квадратик. А когда пол наклонён почти под ноль, он превращается в длинную узкую полосу: поперёк взгляда пиксель накрывает пару текселей, а вглубь — несколько десятков. И подробность сэмплер выбирает одним числом на весь след — по его длинной стороне. Тридцать два текселя вглубь — берётся версия текстуры, уменьшенная в тридцать два раза. Поперечная деталь, которой разрешения хватало с большим запасом, усредняется вместе со всем остальным. Вот и мыло. Причём это не баг, а вынужденный выбор. Возьми сэмплер короткую сторону вместо длинной — вдоль взгляда пошла бы не резкость, а кипящая рябь, потому что там сигнал меняется быстрее, чем его щупают. Одним числом на вытянутый след можно выбрать либо мыло, либо шум. Третьего в этой схеме нет. По сути отсюда и ответ, почему апскейл ассета не помогает: текстура крупнее — обе оси следа растут одинаково, вытянутость остаётся той же. Вы отыгрываете один уровень подробности ценой вчетверо большей памяти, а перекос как был, так и остался. Настройка, которая чинит именно перекос, называется анизотропная фильтрация — та самая строчка «Anisotropic Filtering: 16x» в настройках графики. Она щупает вытянутый след не одной точкой, а несколькими вдоль длинной оси. И приятная часть: число выборок считается для каждого пикселя отдельно. Там, где след круглый — стена перед носом, пол под ногами, — оно равно единице, и никакой доплаты нет. Платят только скользящие углы, а их в кадре обычно меньшинство. Так что это одна из тех галочек, которые дают заметно больше, чем стоят. Ну а самое интересное — дальше. Откуда вообще берётся то самое одно число на весь след и почему в нём стоит именно максимум; сколько на деле стоит ×16 и почему не в шестнадцать раз дороже; и почему выкрученная анизотропия при выключенных мипмапах не работает вовсе — а такую комбинацию встречаешь регулярно. Разберём в пятницу. Там же пол, который можно наклонить ползунком и кликнуть по нему: видно и сам след пикселя в пространстве текстуры, и как в нём выстраиваются точки выборки, когда вы переключаете ×1 → ×16. #геймдев #графика #математика #рендер #текстуры #gamedev

10 000$ за баг в GTA https://youtube.com/shorts/3iJa_wPmGKM?si=pdZ1e-VWVgGtrMhh Семь лет GTA Online грузилась по пять минут — на любом железе. Чинить взялся не Rockstar, а игрок под ником t0st взялся, и хватило ему выходных. И получил за это 10 000$. Оказалось, при каждом входе игра разбирала список из 63 тысяч товаров так, что на каждой позиции пересчитывала всю строку заново. Плюс проверка каждого с каждым на дубли. Около двух миллиардов холостых проверок — и минуты ожидания у миллионов людей. #devmath #разработкаигр #gta #программирование #gamedev

Фильтрация текстур Подошли в игре вплотную к стене — и вместо кирпича размытое пятно. Можно подумать: «фильтрация мылит, пост
Фильтрация текстур Подошли в игре вплотную к стене — и вместо кирпича размытое пятно. Можно подумать: «фильтрация мылит, поставлю point». Ставите — мыло уходит, приходят квадратики. Ощущение, что выбираешь между двумя видами испорченной картинки. Так и есть, и вот почему. Текстура для шейдера — не картинка, а функция: подали координату, получили цвет. Только в памяти лежит конечный массив, и значение каждого текселя — это точка в центре его клетки. Ровно как пиксель на экране, про который мы говорили на прошлой неделе. Когда вы подошли к стене вплотную, на один тексель приходится несколько экранных пикселей — и между известными точками надо что-то придумать. Nearest придумывает «возьму ближайшую» — получаются квадратики. Билинейная фильтрация придумывает «смешаю четыре соседние точки по расстоянию» — получается плавно, то есть мыло. Новой информации ни там, ни там не появилось: обе читают одну и ту же текстуру. Фильтр не создаёт новых деталей — он выбирает, как будет выглядеть их нехватка. Отсюда вывод, который экономит время: если текстура мылит вблизи, крутить фильтр бесполезно. Мылит — значит текселей на этот кусок экрана просто мало. Лечится плотностью текселей: крупнее текстура, мельче тайл на поверхности, отдельная detail-карта поверх — или, если так и задумано, point-фильтр и пиксель-арт как художественное решение (Minecraft именно поэтому и не мылит). И бонус. Если картинка не столько мылит, сколько «чуть мылит и чуть съехала» — обычно это забытые полтекселя. Значение текселя лежит в центре клетки, поэтому при переводе координаты в текселе-пространство вычитают 0.5. Забыли — и вся текстура уехала на полклетки; на кирпичной стене незаметно, на UI и атласах иконок видно сразу. Но самое интересное начинается, когда всё наоборот: не текселей мало на пиксель, а пикселей мало на тексель. Посмотрите на ту же стену не вблизи, а метров с тридцати: в один пиксель попадает уже несколько десятков текселей — и картинка вдали начинает кипеть при малейшем движении камеры. Что там читает сэмплер, откуда берутся уменьшенные копии текстуры и как он выбирает между ними — разберём в пятницу. #devmath #графика #математика #рендер #текстуры #gamedev

Давно не было опросов, а обратная связь мне всегда нужна. Сейчас разбираем компьютерную графику. Тема объективно тяжёлая — я стараюсь излагать просто. Мне важно понять, куда крутить ручку сложности. Выбирайте то, что ближе:

Ну да, на гугле у меня хотя бы препей) А вот клод отключится будет неудобно)

Треугольник становится пикселями https://dev-math.ru/articles/raster/ Вершина добралась до экрана — три точки в пиксельных ко
Треугольник становится пикселями https://dev-math.ru/articles/raster/ Вершина добралась до экрана — три точки в пиксельных координатах. Но сам треугольник ещё не закрашен, а на этом коротком отрезке конвейера живёт своя пачка знакомых багов. Разбираем: — почему тонкий провод вдали мерцает и рвётся; — и почему добавить ему полигонов бесполезно; — отчего далёкие поверхности дерутся полосами друг сквозь друга — и при чём тут near, а не far; — как один и тот же кадр выходит то в пять слоёв, то в один — не тронув ни единого полигона; — почему на PlayStation 1 текстуры «плыли» — и что за одно деление это лечит. #devmath #графика #математика #рендер #растеризация

Мобильный рендер: Дело не в мощности GPU https://youtube.com/shorts/6WtXTERxLaI?si=65mL_ZQZno6b0fdO Так как сейчас у нас недели разбора графики, то я решил попробовать и видосы поделать, как более простой формат подачи информации нежели статьи. Про шину помнить очень важно. Как она загружается и тому подобное. В статье про дроуколлы это разбиралось. Просто где-то с 2017 года я в основном разбирался в том, как запустить красивую картинку на «калькуляторе». Если взять даже этот проект, где нужно было под вебгл с поддержкой мобилки сделать рабочую красивую 3д сцену. Когда нужно завести миллионы полигонов в вебе или что еще страшнее в WebAR, то нужно знать что вертексные параметры можно подрезать. И в этом случае понимать всякие нюансы вроде того же тайлового рендера кадра на мобилках, почему там шина важнее чем на пк и т.п. довольно важно. И знать вообще что такое есть. #devmath #gamedev #unity3d #оптимизацияигр #мобильныйгеймдев

Поговорим про Overdraw Сложная сцена проседает по fps. Первым делом вы идёте резать полигоны: упрощаете меши, расставляете LO
Поговорим про Overdraw Сложная сцена проседает по fps. Первым делом вы идёте резать полигоны: упрощаете меши, расставляете LOD'ы, чистите вершины. Треугольников стало заметно меньше — а кадр не полегчал. Профайлер показывает, что видеокарта всё время сидит в пиксельном шейдере, а не в геометрии. Дело в том, что один пиксель за кадр закрашивается не по разу. Поставьте три объекта друг за другом по глубине: дальше всех стена, перед ней ящик, перед ящиком стойка. Рисуются они в том порядке, в каком их отдал движок, — и если дальняя стена попадёт под кисть первой, она закрасит свои пиксели и целиком отработает шейдер: текстуры, свет, туман. Потом поверх ляжет ящик — и тоже целиком. Потом стойка. На экране виден только ближний слой, а пиксельный шейдер отработал по числу слоёв. Это и есть overdraw — работа, оплаченная за пиксели, которые в итоге никто не увидит. Плотный интерьер, свалка пропов, наслоённые полупрозрачные эффекты — там overdraw набегает быстро. Горит fillrate. Fillrate (филлрейт) — это скорость, с которой видеокарта заливает пиксели в буфер кадра: её пропускная способность на закраску, отдельная от пропускной способности на геометрию. Поймать довольно просто. Подведите камеру вплотную к скоплению объектов: если fps проседает там, где в кадр влезает даже меньше геометрии, но она плотно перекрывается по глубине, — вы уперлись в overdraw, а не в треугольники. А ещё лучше — включите режим overdraw: он есть у Unity, Unreal и мобильных профайлеров. Места, перекрашенные много раз, светятся всё ярче. Это буквально ваш счёт за кадр, нарисованный поверх сцены, — один раз увидев его, вы перестаёте гоняться за полигонами. Видеокарта умеет выбрасывать перекрытые пиксели ещё ДО того, как посчитает их шейдер. Но у этого механизма есть условие, и когда объекты рисуются «как легли в сцене», условие не выполняется — и каждый невидимый слой всё равно оплачен. Что это за условие и что делать, когда шейдеры настолько дорогие, что и сортировка не спасает, — разберём в пятницу. #devmath #графика #математика #рендер #оптимизация #gamedev

Как вы получаете пиксель Далёкие провода ЛЭП, перила моста, ванты, тонкая антенна на крыше — вроде на месте, но стоит чуть по
Как вы получаете пиксель Далёкие провода ЛЭП, перила моста, ванты, тонкая антенна на крыше — вроде на месте, но стоит чуть повести камерой, и линия начинает рваться: тут кусок есть, тут его нет, и всё это дрожит. Первое объяснение, которое приходит в голову: «ну, деталь мельче пикселя, разрешения не хватает». Оно почти верное, но только почти. Растеризатор (узел, который превращает три вершины в закрашенные пиксели) не считает, какую долю пикселя накрыл треугольник. Для него пиксель — вообще не маленький квадратик, который можно зацепить краем. Пиксель — это одна точка в его центре. И треугольник закрашивает пиксель тогда и только тогда, когда накрывает эту точку. Так записано в правилах растеризации Direct3D, так же ведут себя OpenGL и Vulkan. Собственно, отсюда и мерцание. Он не «слишком маленький» — он проходит между центрами пикселей. Камера сдвинулась на полпикселя: где-то центры попали внутрь, где-то нет — по линии побежали мерцающие дырки. Вывод: тонкую геометрию не чинят геометрией. Добавить проводу полигонов бесполезно — толще в экранных пикселях он от этого не станет. Работает другое: держать деталь шириной хотя бы в пиксель на экране (билборд или шейдер, который не даёт ширине упасть ниже пикселя), брать несколько точек покрытия на пиксель (MSAA), либо увести деталь из геометрии в текстуру, где у неё есть альфа и фильтрация. Если у вас мерцают перила — разговор не про меш, а про то, чем вы их рисуете. Ну и крайний случай: треугольник может не нарисоваться совсем. Не за экраном и не за стеной — просто ни одна точка-сэмпл не попала внутрь. Мелкий треугольник или длинный тонкий слайвер проскакивает в зазоре между центрами и не даёт в этом кадре ни одного фрагмента, хотя площадь у него есть и вершины на месте. Сдвинулись на полпикселя — даёт. Для геометрии размером около пикселя вопрос «виден или нет» решает субпиксельная позиция. И из того же правила растёт вопрос, о котором обычно не думают. А если точка-сэмпл легла ровно на ребро, общее у двух соседних треугольников меша? Закрасить у обоих — по шву пройдёт двойная краска, на прозрачности это заметный тёмный рубец. Не закрасить ни у кого — по мешу побежит строчка дырок. Железо этот случай разруливает, и разруливает одинаково у всех. Как именно растеризатор решает «внутри или снаружи», как он поступает с сэмплом на общем ребре и кто из тысячи треугольников, попавших в один пиксель, остаётся на экране — разберём в пятницу. #devmath #графика #математика #рендер #растеризация #gamedev

Квиз: Как игры рисуют кадр? https://youtube.com/shorts/F6enWvT6lQk?si=pXOCdl87qk5F6BiC А что вы думали? Статьи просто так? А
Квиз: Как игры рисуют кадр? https://youtube.com/shorts/F6enWvT6lQk?si=pXOCdl87qk5F6BiC А что вы думали? Статьи просто так? А ну взяли ручки и проходим контрольную. По статье по дроуколлам и пространствам. Собрал небольшой видео-квиз. Такие штуки вообще проходить полезно, так как информация лучше запоминается, когда с ней сталкиваешься несколько раз в разных контекстах. Хотя мы пока разбираем только базу. #геймдев #игры #графика #квиз #devmath

Где на экране этот треугольник https://dev-math.ru/articles/spaces/ Всю неделю я рассказывал о том где именно находится верши
Где на экране этот треугольник https://dev-math.ru/articles/spaces/ Всю неделю я рассказывал о том где именно находится вершина. Что камеру в 3D на самом деле не двигают — двигается весь мир вокруг неё. Что далёкие поверхности мерцают не из-за материалов, а из-за near, прижатого к нулю. Обещанная статья готова: проходим дорогу одной вершины целиком — от строчки в вашем коде до конкретного пикселя на экране. Плюс разбор, почему отметка Static и статик-батчинг в Unity вообще не спорят с «мир едет навстречу камере». #devmath #графика #математика #3d #mvp #проекция