Другие материалы: симуляция огня, симуляция воды
Рассмотрим простую, но очень важную технику, которая широко применяется в 2D-играх: параллакс. Это греческое слово обозначает разницу положений объекта, когда мы смотрим на него с разных позиций. Если мы смотрим на 2 дерева: одно вблизи, а другое вдали, то шагнув на пару метров вправо или влево, мы увидим, что ближнее к нам дерево сместилось сильнее, чем дальнее. Наш мозг натренирован так, чтобы по параллаксному смещению определять расстояние до объекта.
Давайте посмотрим на эту схему:
У глаза есть угол зрения. И как можно видеть, в угол зрения помещается разное количество объектов на разных расстояниях. Вблизи мы можем увидеть только одно дерево целиком. Дальше можно увидеть сразу три дерева. И ещё дальше можно увидеть 5 деревьев. Как так получается? Оптическая система глаза устроена таким образом, что чем дальше объект – тем он меньше, несмотря на то, что его физический размер остаётся постоянным. Своими глазами мы видим примерно такую картину:
И если мы сдвинемся влево или вправо на одно дерево, то в каждом ряду произойдет одинаковый сдвиг на одно дерево. Но только в ближнем ряду этот сдвиг будет равен 167 пикселов, в среднем 85 пикселов, а в дальнем 50 пикселов. Вот и получается, что хоть каждый ряд сдвинулся ровно на 1 дерево, но сам сдвиг чем дальше, тем меньше.
Таким образом, 2D-сцены, в которых присутствует параллакс, воспринимаются нами как имеющие глубину. Чем сильнее смещается объект относительно других объектов – там ближе он к нам. В играх параллакс используется для создания разных эффектов, и давайте начнём с движения в космосе сквозь звёзды. Звёзды изображаются точками на экране, и если бы они не двигались, мы не могли бы сказать, какая из них находится дальше, а какая ближе:
Но как только они начинают двигаться с разными скоростями, создаётся иллюзия, что те звёзды, которые движутся быстрее – находятся ближе (см. работающую в браузере программу по ссылке).
Однако это фальшивка. Я просто генерирую звёзды со случайными скоростями, которые движутся в направлении из центра экрана к его краям. Это создаёт иллюзию параллакса, но не подкреплено реальной математикой. Получится ли более убедительная глубина, если применить реальный параллакс?
Первое, что нужно сделать – это получить зависимость смещения объекта от расстояния. Посмотрим на схему с одной звездой:
Если нижняя полоска это плоскость экрана, то положение звезды на ней пропорционально положению звезды в своей плоскости (верхняя полоска). То есть положение звезды на плоскости экрана относится к положению звезды в своей плоскости так же, как расстояние до экрана относится к расстоянию до плоскости звезды.
экранная_x_звезды = x_звезды * расстояние_до_экрана / расстояние_до_плоскости_звезды
Если что, мы получили формулу перспективной проекции.
Теперь я сделаю следующее:
- Звёзды будут иметь координаты x, y, z, где z – это расстояние от наблюдателя
- Установлю самое далёкое расстояние, с которым можно работать (это подберу экспериментально)
- Сгенерирую массив звёзд, имеющих случайные координаты x, y и случайное расстояние z между плоскостью экрана и самым далёким расстоянием
- Все сгенерированные звёзды будут в каждом кадре приближаться, сокращая расстояние z
- Все сгенерированные звёзды будут отображаться на плоскость экрана по вышеуказанной формуле.
- Все звёзды, которые достигли плоскости экрана, или чья проекция на экран выходит за пределы экрана, будут отправляться на переработку – координаты x, y будут генерироваться заново, а расстояние будет задано максимальное, то есть вдали будет появляться новая звезда вместо старой. Я пускаю звёзды в переработку, чтобы не связываться с операциями удаления и добавления в массиве.
И вот что получилось: (см. работающую в браузере программу по ссылке)
Мне кажется, теперь звёзды движутся гораздо более убедительно. Хотя и первый вариант был по-своему интересен. Как вы думаете?
В следующих выпусках рассмотрим другие применения параллакса: дождь, снег и параллакс-скроллинг.