Чтобы делать классные 3D-игры
Помните, когда мы в школе проходили все эти синусы, косинусы и углы, у всех был вопрос — а как нам это пригодится в жизни? Тогда казалось, что это нужно только учёным и математикам, но на самом деле всё трёхмерное моделирование и 3D-игры — это та самая школьная тригонометрия.
При чём тут 3D
В одной из статей мы рассказывали про 3D-игру Doom. Одной из особенностей этой игры было то, что у неё не было настоящей трёхмерной графики — движок оперировал двумерными моделями. Но на экране казалось, что это настоящая трёхмерность:
- можно было понять, что находится ближе, а что — дальше;
- если подойти к двери, она увеличивалась, а если отойти — уменьшалась;
- когда враги приближались, они становились больше, а на горизонте их было почти не видно и так далее.
Всё дело — в угле зрения. От него зависит, каким будет казаться объект, маленьким или большим, и как он изменит свой размер на разных расстояниях.
Угол зрения
Чтобы понять, что такое угол зрения, нам нужно знать всего две величины — высоту объекта и расстояние до него:
Сейчас наблюдателю наш красный объект кажется далёким, потому что угол зрения — маленький. Но если мы подвинем этот объект поближе к наблюдателю, то угол зрения станет больше:
Теперь наблюдателю кажется, что объект очень близко, потому что угол зрения стал гораздо больше, чем раньше. Получается, что угол зрения влияет на то, как мы воспринимаем предметы — близкими или далёкими.
И вот тут нам пригождается школьная тригонометрия — все эти синусы, косинусы и тангенсы. Благодаря им мы сможем рассчитывать нужный размер предметов на экране в зависимости от того, какой угол получится между нашей виртуальной камерой и разницей в высоте предмета. Это позволит нам смоделировать разное расстояние до предметов, как будто у двумерного плоского экрана появляется третье измерение — глубина.
Ненастоящее 3D в DOOM
Из школьной программы мы помним формулу тангенса:
tg α = высота / расстояние, где α — наш угол зрения.
Единственное, что отличает на экране далёкие предметы от близких, — это высота, поэтому мы можем регулировать её так:
высота = расстояние × tg α.
Если расстояние будет равно единице, то высота объекта — это просто будет тангенс угла зрения альфа.
А раз так, то мы можем это использовать для эффекта 3D:
- Берём любой объект
- Выясняем, какой будет угол зрения для этого объекта, если подойти к нему вплотную, насколько позволяет игровой движок.
- Теперь если нам нужно показать, что мы отходим от объекта, то мы просто уменьшаем угол зрения. С ним уменьшится и тангенс, и высота объекта на экране.
- То же самое и с приближением — чтобы показать на экране, что мы как будто подходим к объекту, мы просто увеличиваем угол зрения, а с ним увеличивается и высота. Кажется, что мы подошли поближе.
Как видите, тут нигде нет расстояния до объекта — только угол зрения, который создаёт эффект приближения или удаления. Чистая тригонометрия.
Настоящее 3D
В настоящем 3D синусы и косинусы нужны, чтобы посчитать новые координаты всех сторон движущегося объекта. Штука в том, что нам нужно перенести объёмный трёхмерный объект на плоский двумерный экран — сделать проекцию.
На плоской поверхности у нас есть только две координаты — X и Y, поэтому нам нужны формулы, которые помогут учесть третью координату Z и нарисовать объект так, чтобы он выглядел объёмным:
x':=x*sin(угол между плоскостью XOY и отрезком OZ) ;
y':=y*cos(угол между плоскостью XOY и отрезком OZ) ;
Чтобы трёхмерные объекты на экране можно было двигать, тоже используют тригонометрию. Например, если у нас есть трёхмерный кубик, у вершин которого есть координаты x, y и z, то, чтобы его повернуть на угол L по оси X, нужно сделать такое для каждой вершины:
x'=x;
y':=y*cos(L)+z*sin(L) ;
z':=-y*sin(L)+z*cos(L) ;
Здесь x', y' и z' — новые координаты вершины. Если мы нарисуем кубик с такими новыми координатами каждой вершины, то будет казаться, что мы его немножко повернули.
Для других координат это работает похожим образом — нужно просто знать угол поворота для каждой оси, чтобы правильно посчитать новые координаты.
Чтобы показать, как это работает, давайте сделаем HTML-страницу, которая нарисует нам вращающийся кубик. Мы прокомментировали каждую строку кода, чтобы вы тоже смогли понять, что там происходит. Это настоящее 3D, для которого тоже нужна школьная тригонометрия:-)
Сохраните себе этот код как HTML-документ и откройте в браузере, чтобы посмотреть на вращение кубика. Если не знаете, как это сделать, — вот подробный гайд в помощь: Спасательный круг для тех, кто начинает писать на JavaScript
Код страницы с 3D-кубиком вы можете найти в статье: https://v.thecode.media/ggpre