889

Зачем нужна математика в компьютерных играх? [часть 1]

Привет-привет.

Почти 200 дней назад я написал комментарий под одним из постов, в котором немножко популярно объяснил, зачем в компьютерных играх (и компьютерной графике вообще) нужна линейная алгебра. Тот самый линал, что любой студент-технарь изучает на 1 курсе универа.


О том, что пост мне пилить лень, я предупредил сразу, но пикабушников это не убедило, у меня прибавилось over 100 подписчиков (с одного коммента-то!), так что почему бы и нет.


Примечание: рассказывать я буду с расчётом на людей, понимающих, что такое матрица, вектор и cross product, но, несмотря на это, постараюсь всё объяснить и расписать понятно даже для гуманитария (в идеале, линал для понимания поста изучать не нужно).


Как говорил Стивен Хокинг, «Любая формула уменьшает количество моих читателей вдвое». Пока, ребят).

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Чуть-чуть школьной геометрии. Что такое вектор? Это стрелка. У неё есть длина и направление. Есть двумерные векторы (у которых направление — от 0 до 360 градусов), есть трёхмерные (у них есть два направления, оба от 0 до 360).

В абстрактной алгебре есть даже бесконечномерные векторы, но это нам не нужно)

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Вот эта красная стрелка — и есть вектор. Линии, обозначенные буквами x, y, z, — называются умным словом координатные прямые.

Давайте запихнём наш вектор в коробку (оранжевые пунктирные прямые) и померяем её длину, ширину и высоту. Эти значения называются координатами вектора. В частности, здесь это (10, 2, 10). [именно в таком порядке, (x, y, z)]


Теперь если мы кому-нибудь скажем «вектор (10, 2, 10)», он сразу сможет его нарисовать, и это окажется в точности тот же вектор.


В школе на геометрии обычно изучают скалярное произведение двух векторов. Вот оно:

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

А ещё его изучают в универе, на линейной алгебре.


А теперь главное: применение! Давайте представим, что мы хотим нарисовать на экране 3D-модель. Любая 3D-модель состоит из треугольников, и, в общем, нарисовать кучу треугольников рандомным цветом — достаточно лёгкая задача.

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Не слишком привлекательно, да? Давайте попробуем сделать нормальные тени.

Нужно узнать, каким цветом заливать каждый треугольник.


Итак, для начала введём вектор, который начинается в центре модели, а заканчивается там, где и будет источник освещения. А именно — вектор (0, 0, 1).


Так получается потому что ось z направлена на нас, а координаты — что-то вроде процентов, например, точка (0, 0, 0.5) — это точка ровно посередине между центром модели (которая, как мы считаем, находится «позади экрана») и экраном компьютера :)


А теперь давайте проведём из каждого треугольника перпендикулярный ему вектор (причём длины 1) и скалярно перемножим с нашим вектором источника освещения.

Это и будет коэффициент освещённости треугольника:

— если 0, то совсем не освещён, рисуем чёрным.

— если 0.5, то освещён наполовину, рисуем серым 50%.

— если 1, то полностью освещён, рисуем белым.

— и тому подобное.


И наша модель обретает жизнь!

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Есть и более продвинутые модели освещения (например, Фонга), про них, возможно, напишу в будущем, но вряд ли.

И небольшое примечание про перпендикулярные векторы.

Перпендикуляр треугольника находится с помощью векторного произведения: берём любые 3 точки треугольника и составляем из них 2 вектора. Векторное умножение выглядит так:

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Как видно, скалярное произведение — число, а векторное произведение — вектор.


Нужно ещё сделать, чтобы перпендикуляр был длиной 1, а это операция нормирования вектора:

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

С кодом модели можно поиграться тут: http://jsfiddle.net/2wvyga24/24/ .

Также можно почитать статьи хабраюзера haqreu: https://habrahabr.ru/post/248153/ .

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Матрицы — это главная причина, по которой всё, что в играх должно вращаться или двигаться, вращается или двигается. И это именно то, как работает Free Transform в фотошопе.


Матрица — это обычная табличка с числами. Их даже можно складывать и умножать.

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост
Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Если сложение — достаточно очевидная вещь, то вот умножение...

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Запоминается простым правилом «строка на столбец». Берём 2 строку первой матрицы и скалярно умножаем на 1 столбец второй. Это и будет элемент, стоящий во 2 строке 1 столбца произведения.

Казалось бы, зачем так усложнять? Почему не умножать обычным образом?


Разгадка проста: изначально матрицы были придуманы, чтобы решать уравнения. Но это мы не будем затрагивать...

Ведь вдруг оказалось, что матричное умножение — это то, что делает матрицы столь полезными для компьютерной графики!

А ещё можно матрицы умножать на векторы. По обычному правилу: по сути, вектор — и есть матрица, просто с одним столбцом (или одной строкой, но это совсем отдельная тема).

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Давайте возьмём плоскость и засунем любую картинку в нулевые координаты (т.е. левый нижний угол квадратика с кексом имеет координаты 0,0).

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Как её теперь повернуть на 45 градусов? Картинка ведь состоит из точек (пикселей), и нужно найти новые координаты для каждой точки. Нужна какая-нибудь формула.


И она есть!


Итак, любая точка с координатами (x, y) — по сути, вектор с координатами (x, y) же. Умножение на матрицу 2×2 — это преобразования пространства (сжатие, поворот и тому подобное).


И поворот выглядит вот так:

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Координаты x', y' — это и есть новые координаты после поворота.

А вот масштабирование (увеличение / уменьшение) — на λ по x и на η по y.

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

И наконец, «cкос», также известный как Skew / Shear. Фотошоперы поймут).

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Поскольку ничего не понятно, вот утащенная из интернета картинка:

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Например, мы повернули картинку на 30 градусов, а затем увеличили в 3 раза по вертикали и в 2 по горизонтали.

Тогда пиксель с координатами (50,30) перейдёт в пиксель с координатами (2, 175):

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Я же ничего не перепутал, да?


Все наши преобразования происходят вокруг начала координат — точки (0, 0). Если мы хотим повернуть картинку вокруг центра, нужно вставлять её так, чтобы центр картинки оказался в точке (0, 0).


Увы, перемещения с помощью матрицы выразить нельзя. Так что был придуман небольшой хак: давайте перейдём к матрицам и векторам 3×3:

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост
Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Все предыдущие преобразования остаются в силе:

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Но теперь мы можем выразить перемещения!

Зачем нужна математика в компьютерных играх? [часть 1] Линейная алгебра, Алгебра, Математика, Игры, Графика, Длиннопост

Ну что ж, теперь несколько хороших моментов:


— Умножение матриц не перестановочно, т.е. обычно A × B ≠ B × A. От перестановки множителей меняется произведение. Например, [переместить на x,y и повернуть на φ] — не то же самое, что [повернуть на φ и переместить на x,y].


— Однако ассоциативно, т.е. (A × B) × C = A × (B × C).


— А значит, перемножение матриц даёт суммарное преобразование. Например: A — поворот, B — перенос, C — масштаб. Тогда матрица A × B × C — это всё сразу. И произведение матрицы (A × B × C) на вектор — это преобразование вектора всеми тремя способами на все те же координаты.


— Обратная матрица — обратное преобразование. Например, поворот на 30 градусов — поворот на -30. Увеличение вдвое — увеличение в 0.5.


И самое важное:

— Всё это переносится практически без изменений в трёхмерное пространство. Векторы и матрицы становятся четырёхмерными (чтобы выражать перемещения), появляется несколько видов поворотов... ну и всё.

P. S. вероятно, следующие посты не будут публиковаться в сообщество.

P. P. S. поскольку мне лень, ждать продолжения бывает долго х)


Вопросы в комментарии :D

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"

Вы смотрите срез комментариев. Показать все
16
Автор поста оценил этот комментарий
Спасибо, матрицы не особо понял, но вот вектора объяснили замечательно)
Я так понимаю, больше не стоит подобных постов от вас ждать?
раскрыть ветку (19)
9
Автор поста оценил этот комментарий

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

раскрыть ветку (3)
4
Автор поста оценил этот комментарий

Да, к сожалению.

Я выкинул немалую часть поста. Например, про то, как матричное умножение связано с линейными уравнениями.

Просто потому что с доказательствами и выводами этот пост увеличится раза в 3. А количество читателей и интересующихся в целом — уменьшится, примерно во столько же.


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

Кому не нужно, — прочитали, "ух ты, интересно", и забыли.)

раскрыть ветку (2)
1
Автор поста оценил этот комментарий
Ну так и должно быть. Тут то получается плюсиков поставили и человек ничего не понял или уже понимал, что тут творится
раскрыть ветку (1)
2
Автор поста оценил этот комментарий

Так хотя бы человек заинтересовался и пошёл раскапывать инфу. А если будет пост, перенасыщенный кучей формул, заинтересовавшихся будет значительно меньше.


Хорошо, я попробую в следующих постах объяснять, откуда что берётся.)

6
Автор поста оценил этот комментарий
Иллюстрация к комментарию
раскрыть ветку (6)
6
Автор поста оценил этот комментарий
Видимо настолько подъебал, что не заметил СВОЕГО же подъеба.
Вы о чем, молодой человек?
раскрыть ветку (4)
4
Автор поста оценил этот комментарий

Сделали упор на "молодой человек", будто хотели себя возвысить надо мной : /


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

раскрыть ветку (3)
2
Автор поста оценил этот комментарий

Ну я пока загорелся этой темой, так что есть шанс, что в ближайшее время будет что-нибудь ещё)

раскрыть ветку (2)
2
Автор поста оценил этот комментарий
Я поправил)

Ну я пока загорелся этой темой, так что есть шанс, что в ближайшее время будет что-нибудь ещё

(на самом деле нет)

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Да, так, пожалуй, вернее)

2
Автор поста оценил этот комментарий
Projdemte.
0
Автор поста оценил этот комментарий

Слово "часть 1" в заголовке намекает, что продолжение будет.

Как я уже выше написал, после векторов кончились силы, так что матрицы объяснить настолько наглядно, насколько хотел, не смог.

раскрыть ветку (7)
0
Автор поста оценил этот комментарий

Откуда мы знаем, что значит 1? Часть первая? Часть одна? Или часть единственная? (в духе математики вопрос:D)

раскрыть ветку (1)
Автор поста оценил этот комментарий

"Откуда мы знаем, что под 1 ты имеешь в виду то же, что и мы?" :D

0
Автор поста оценил этот комментарий

Про матрицы понятно, но у меня вопрос: у меня есть датчик( акселлерометр+гироскоп ) и я хочу сделать инерциальный захват движений. На входе ускорения по трем осям и угловые по трем, каждый кадр я должен эти значения добавлять к координатам( в зависимости от углов ) и к углам. Как это сделать?

раскрыть ветку (4)
2
Автор поста оценил этот комментарий

инициируете вектор положения, вектор скорости, угла например нулями

с акселерометра приходит вторая производная линейных координат, с гироскопа - первая производная поворота (скорее всего, если не аппаратно спарен с магнетометром)

это значит:

каждый замер с акселерометра (da) - умножаем на время, прошедшее с прошлого замера (dt) - получим дельту скорости (dv). ее добавляем к вектору скорости. далее новый вектор скорости умножаем на то же время dt - получаем дельту расстояния (ds). ее добавляем к вектору положения

с гироскопа надо просто умножить на dt и добавить к вектору угла


надо помнить, что:

1. чем чаще опрашиваем датчик - тем точнее будет результат, т.к за меньшее время значение изменится незначительно, а за большее - можно продолбать пики, спады

2. ошибка интегрирования ускорения растет сильно быстрее, чем поворота (т.к. нужно два интегрирования)

3. многие датчики имеют внутренний интегрирующий сопроцессор с буфером - почитайте даташиты. они умеют более точно делать то, что я описал выше (быстрее опрашивают датчики, точнее измеряют время)

4. гироскоп имеет штатный дрейф из-за вращения земли. поищите соотвествующие данные для вашей широты


когда-то был немного в теме, пишите если чо

Автор поста оценил этот комментарий

Я не разбираюсь в гироскопах, вот от слова "совсем".

Само собой напрашивается умножать ускорения на дельту по времени и на косинусы (или синусы) углов. Но я тебе лучше советую погуглить

раскрыть ветку (2)
0
Автор поста оценил этот комментарий

Попробую спросить по другому: есть самолет, у него углы yaw pitch roll( по осям z, y, x к примеру ), самолет имеет уже какие то углы, как поворачивать этот самолет по углам как на картинке?

Иллюстрация к комментарию
раскрыть ветку (1)
Автор поста оценил этот комментарий

Ах да!

По-моему, здесь нужны кватернионы. Как раз то, о чём я собирался рассказать в следующем посте. Но, т.к. он может быть нескоро, то вкратце: кватернион — это как комплексное число, только в 2 раза хуже.

Если комплексное число — это a+bi с условием i^2 = -1, то кватернион — это a+bi+cj+dk с условием i^2 = j^2 = k^2 = ijk = -1.


Отсюда выводится сложение и умножение кватернионов. Если лень, то всё гуглится :)


Далее. Поворот на угол (a,b,c) представляется как кватернион i*cos a + j*cos b + k*cos c. Перемножение двух таких кватернионов даёт суммарный поворот.


Вот как-то так.


Извини, если снова что-то неправильно понял: очень устал за сегодня, ничего не соображаю)

Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку