Обучение технологии ray-casting. Часть 2

от автора

Приветствую тебя, читатель. Это вторая часть серии переводов работы «Ray-Casting Tutorial For Game Development And Other Purposes». Второй части предшествует первая, которую так же можно просмотреть.

Начнем! Продолжим!

Ограничения ray-casting

Технология ray casting быстрая потому, что она использует некоторые геометрические ограничения. В большинстве случаев стены всегда перпендикулярны полу (заметьте, что это не касается углов между самими стенами).

Отсюда мы получаем еще одно ограничение: точка обзора не может вращаться вдоль оси Z (которую мы все знаем, как ось аппликата — прим. пер.). Почему? Представим обратное: вращение разрешено. В таком случае стены могут наклоняться, и соответственно теряется преимущество отрисовки вертикальных срезов этих самых стен. Ограничение во вращении является одной из причин, почему технологию ray casting нельзя считать полноценным 3D.

Технология ray-casting позволяет игроку двигаться вперед/назад и поворачиваться вправо/влево, но не вращаться вокруг оси Z (такой тип вращения называется креном (если ось Y вертикальная, то вращение по ней — тангаж, а по оси X — рыскание, — прим. пер.)).

Шаг 1: Создание окружения

Для то, чтобы отобразить работу ray casting, мы создадим сцену в виде лабиринта, которая будет основываться на следующих геометрических ограничениях:

  • Стены всегда перпендикулярны полу

  • Стены представляют собой одинакового размера кубы

  • Пол всегда лава плоский

Каждый куб будет иметь размер 64x64x64 (Выбор произвольный, но полезно иметь такое число, которое будет являться степенью 2. В таком случае мы сможем использовать операцию битового сдвига, которая работает быстрее умножения и деления). Стоит отметить, что чем больше размер блоков, тем более кубическим будет казаться наш мир, с другой стороны, слишком маленькие блоки ввиду их большого количества замедлят процесс рендера.

Перед тем как продолжить, мы должны определить систему координат (далее — СК), чтобы далее не было каких-либо недопониманий. Наша СК изображена на следующем рисунке.

Любая картезианская СК также будет работать. Тем не менее, будьте последовательны и не используйте разные СК. Иначе вы можете запутать себя — проверено мною лично.

Шаг 2. Определение атрибутов проекции

Перед тем, как начать проецировать и ренедрить созданную сцену, нужно определить некоторые атрибуты. Вот они:

  • Высота игрока, поле зрения игрока (FOV — Field Of View), и координаты игрока

  • Размеры плоскости проекции

  • Как соотносятся игрок и плоскость проекции

Игрок должен иметь возможность видеть то, что находится напротив него. Для этого мы объявим FOV, который определит, насколько широкая область сцены доступна для наблюдения игроком. Люди имеют FOV в 90° и больше. Тем не менее, такой угол не совсем подходит для экранов ПК. Мы выберем 60°, которые были получены путем экспериментов и проб (насколько хорошо выглядит картинка с таким-то углом FOV). Высоту игрока определим, как 32 единицы. Это вдвое меньше, чем стены, что является разумным допущением. (если взять реальное соотношение средней высоты помещения к среднему росту человека-самца, то получим: 2.4  / 1.7 = 1.41 — прим. пер.).

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

Чтобы поместить игрока в наш мир, нужно для этого игрока определить X-координату, Y-координату и угол поворота. Эти 3 атрибута формируют POV (point of view) игрока.

Если предположить, что игрок где-то по центру координатной сетки (1, 2), и его угол поворота равен 45 относительно начала оси, то FOV будет выглядеть примерно, как на картинке ниже. (Каждый элемент сетки имеет размеры 64×64 единиц).

На картинке слева мы видим POV, которая представляет собой координаты игрока и его угол поворота. На картинке справа — FOV — область видимости игрока. — прим. пер.

Нам нужно определить плоскость, на которую мы будем проецировать то, что видит игрок. Плоскость шириной в 320 единиц и высотой в 200 — это хороший выбор, т.к. это разрешение большинства VGА видеокарт.

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

Как только нам стали известны FOV и размеры плоскости проекции мы можем посчитать угол между последующими лучами и расстояние между игроком и плоскостью проекции.

Что мы имеем:

На картинке слева мы видим плоскость проекции того, что видит игрок (это же экран нашего монитора): она имеет размеры 320х200 пикселей и центр в точке (160, 100). На картинке справа представлен вид «из глаз игрока». — прим. пер.

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

FOV равен 60. При этом мы видим плоскость проекции шириной в 320 пикселей, то есть 60° соответствуют 320 столбцам и, следовательно, 1 столбец равен 60 / 320 градусам. — прим. пер.

FOV и плоскость проекции образуют равнобедренный треугольник. Если к плоскости проекции провести высоту, то мы получим два прямоугольных треугольника с одной стороной в 320 / 2 = 160 единиц и углами: 90°, 60° / 2 = 30° и 90° — 30° = 60° соответственно. Используя формулы тригонометрии мы находим длину высоты (277), которая и является расстоянием между игроком и плоскостью проекции. — прим. пер.

По итогу нам известно:

  • Размеры плоскости проекции (экрана) = 320х200 единиц

  • Центр плоскости проекции (160, 100)

  • Расстояние до плоскости проекции = 277 единиц

  • Угол между последующими лучами = 60 / 320 градусов

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

Конец второй части

ссылка на оригинал статьи https://habr.com/ru/post/517774/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *