Статьи

Переосмысление Flight Simulator: тогда и сейчас

Эта статья является частью серии веб-разработки от Microsoft. Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.

Первая версия Flight Simulator была выпущена в 1980 году для Apple II и, что удивительно, была в 3D! Это было замечательное достижение. Еще более удивительно, если учесть, что все 3D было сделано вручную, в результате тщательных вычислений и низкоуровневых команд пикселей. Когда Брюс Этвик занялся ранними версиями Flight Simulator, не только не было 3D-фреймворков, но вообще не было фреймворков! Эти версии игры были в основном написаны на ассемблере, всего в одном шаге от единиц и нулей, которые проходят через процессор.

Когда мы решили переосмыслить Flight Simulator (или Flight Arcade, как мы его называем) для Интернета и продемонстрировать, что возможно в новом браузере Microsoft Edge и движке рендеринга EdgeHTML , мы не могли не думать о контрасте создания 3D, тогда а теперь — старый Flight Sim, новый Flight Sim, старый Internet Explorer, новый Microsoft Edge. Современное кодирование кажется почти роскошным, когда мы создаем трехмерные миры в WebGL с помощью великолепных фреймворков, таких как Babylon.js . Это позволяет нам сосредоточиться на проблемах очень высокого уровня. В этой статье мы расскажем о нашем подходе к одной из этих забавных задач: простому способу создания реалистично выглядящего крупномасштабного ландшафта.

Примечание. Интерактивный код и примеры для этой статьи также расположены по адресу: http://www.flightarcade.com/learn/.

Моделирование и 3D рельеф

Большинство 3D-объектов создаются с помощью инструментов моделирования, и на то есть веские причины. Создавать сложные объекты (например, самолет или даже здание) сложно в коде. Инструменты моделирования почти всегда имеют смысл, но есть исключения! Одним из таких случаев могут быть, например, холмы острова Полетной Аркады. В итоге мы использовали технику, которая показалась нам более простой и, возможно, еще более интуитивной: карту высот.

Карта высот — это способ использовать обычное двумерное изображение для описания рельефа поверхности, такой как остров или другая местность. Это довольно распространенный способ работы с данными высотных отметок не только в играх, но и в географических информационных системах (ГИС), используемых картографами и геологами.

Чтобы помочь вам понять, как это работает, посмотрите интерактивную карту высот ниже. Попробуйте нарисовать в редакторе изображений, а затем проверьте получившийся ландшафт.

Изображение1-интерактивно-демо-высот

Попробуйте интерактивную демонстрацию здесь.

Концепция карты высот довольно проста. На изображении, подобном приведенному выше, чистый черный — это «пол», а чистый белый — самый высокий пик. Промежуточные цвета в градациях серого представляют соответствующие высоты. Это дает нам 256 уровней высоты, что достаточно для нашей игры. Реальные приложения могут использовать полноцветный спектр для хранения значительно большего количества уровней детализации (256 4 = 4 294 967 296 уровней детализации, если вы включите альфа-канал).

Карта высот имеет несколько преимуществ по сравнению с традиционной полигональной сеткой:

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

Во-вторых, карты высот — это удобный способ создания, визуализации и редактирования ландшафта. Это довольно интуитивно понятно, когда вы видите один. Это немного похоже на просмотр карты. Это оказалось особенно полезным для Flight Arcade. Мы разработали и отредактировали наш остров прямо в Photoshop! Это позволило очень легко вносить небольшие корректировки по мере необходимости. Когда, например, мы хотели убедиться, что взлетно-посадочная полоса была абсолютно плоской, мы просто закрасили эту область одним цветом.

Вы можете увидеть карту высот для Flight Arcade ниже. Посмотрите, сможете ли вы найти «плоские» участки, которые мы создали для взлетно-посадочной полосы и деревни.

image2-для-высот-The-летный аркадный остров

Карта высот острова Аркадных Полётов. Он был создан в Photoshop и основан на «большом острове» в знаменитой цепочке островов Тихого океана. Есть догадки?

image3-текстуры-отображение-3d-результаты

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

Расшифровка карты высот

Мы создали Flight Arcade с Babylon.js, и Babylon дал нам довольно простой путь от карты высот до 3D. Babylon предоставляет API для генерации геометрии сетки из изображения карты высот:

image4-кода в создании-высот

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

20 подразделений

знак равно

400 ячеек

50 подразделений

знак равно

2500 ячеек

100 подразделений

знак равно

10000 клеток

500 подразделений

знак равно

250000 клеток

1000 подразделений

знак равно

1 000 000 клеток

В следующем разделе мы узнаем, как текстурировать землю, но, экспериментируя с созданием карты высот, полезно увидеть каркас. Вот код для применения простой каркасной текстуры, поэтому легко увидеть, как данные карты высот преобразуются в вершины нашей сетки:

image5-простой каркасный-материал

Создание текстуры детали

Когда у нас была модель, наложение текстуры было относительно простым. Для Flight Arcade мы просто создали очень большое изображение, которое соответствует острову в нашей карте высот. Изображение растягивается по контурам местности, поэтому текстура и карта высот остаются коррелированными. Это было действительно легко визуализировать, и, опять же, вся производственная работа была сделана в Photoshop.

Исходное изображение текстуры было создано в 4096 × 4096. Это довольно большой! (В конечном итоге мы уменьшили размер до уровня 2048 × 2048, чтобы обеспечить разумную загрузку, но вся разработка была сделана с полноразмерным изображением). Вот пример полного пикселя из оригинальной текстуры.

image6 набитые пикселы образец из-аркады-остров-изображение

Пиксельный образец оригинальной текстуры острова. Весь город занимает площадь около 300 пикселей.

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

Чтобы это исправить, мы «смешали» дополнительные детали с текстурой ландшафта в виде случайного шума. Вы можете увидеть до и после ниже. Обратите внимание, как дополнительный шум улучшает внешний вид деталей на местности.

image7-дополнительный-деталь-с-смесь

Мы создали собственный шейдер, чтобы добавить шум. Шейдеры дают вам невероятный контроль над рендерингом 3D-сцены WebGL, и это отличный пример того, как шейдер может быть полезен.

Шейдер WebGL состоит из двух основных частей: вершинных и фрагментных шейдеров. Основная цель вершинного шейдера — отобразить вершины на позицию в визуализированном фрейме. Фрагмент (или пиксельный) шейдер контролирует результирующий цвет пикселей.

Шейдеры написаны на языке высокого уровня, который называется GLSL (Graphics Library Shader Language), который похож на c. Этот код выполняется на GPU. Подробное описание работы шейдеров приведено в этом руководстве, посвященном созданию собственных шейдеров для Babylon.js.

Вершинный шейдер

Мы не меняем способ отображения нашей текстуры на основную сетку, поэтому наш вершинный шейдер довольно прост. Он просто вычисляет стандартное отображение и назначает целевое местоположение.

image8-заместитель vertetdx-шейдер

Фрагмент шейдера

Наш фрагментный шейдер немного сложнее. Он объединяет два разных изображения: базовое и смешанное. Базовое изображение отображается по всей наземной сетке. В Flight Arcade это цветное изображение острова. Смешанное изображение — это изображение с небольшим шумом, используемое для придания земле текстуры и деталей на близких расстояниях. Шейдер объединяет значения из каждого изображения для создания комбинированной текстуры по всему острову.

Последний урок в Flight Arcade проходит в туманный день, поэтому другая задача, которую выполняет наш пиксельный шейдер, — настроить цвет для имитации тумана. Корректировка основана на том, как далеко вершина находится от камеры, причем отдаленные пиксели более «скрыты» туманом. Вы увидите это вычисление расстояния в функции calcFogFactor над основным кодом шейдера.

image9-calcFogFactor-функция

Последняя часть нашего пользовательского шейдера Blend — это код JavaScript, используемый Babylon. Основная цель этого кода — подготовить параметры, передаваемые нашим вершинным и пиксельным шейдерам.

image10-Prepare-параметры-для-шейдера

image11-смесь-материал-прототип

Babylon.js позволяет легко создавать собственные шейдерные материалы. Наш материал Blend относительно прост, но он действительно сильно повлиял на внешний вид острова, когда самолет полетел низко над землей. Шейдеры переносят всю мощь графического процессора в браузер, расширяя типы креативных эффектов, которые можно применять к 3D-сценам. В нашем случае это был последний штрих!

Больше практического опыта с JavaScript

У Microsoft есть много бесплатного обучения по многим темам JavaScript с открытым исходным кодом, и мы стремимся создать намного больше с Microsoft Edge . Вот некоторые, чтобы проверить:

И несколько бесплатных инструментов для начала работы: Visual Studio Code , Azure Trial и кросс-браузерные инструменты тестирования — все это доступно для Mac, Linux или Windows.

Эта статья является частью серии технологий веб-разработки от Microsoft. Мы рады поделиться с вами Microsoft Edge и новым механизмом рендеринга EdgeHTML . Получите бесплатные виртуальные машины или проведите удаленное тестирование на устройстве Mac, iOS, Android или Windows на сайте modern.IE .