Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Документация для продвинутых пользователей
                TerraMonkey - The jMonkeyEngine Terrain System

TerraMonkey — The jMonkeyEngine Terrain System

Опубликованно: 22.06.2017, 20:17
Последняя редакция, Andry: 30.12.2017 16:08

Обзор

TerraMonkey — это дерево квадрантов GeoMipMapping с плитками ландшафта, которое поддерживает редактирование в реальном времени и распределение текстур. Этого более чем достаточно! Давайте посмотрим на каждую часть:

  • GeoMipMapping: метод изменения уровня детализации (LOD) геометрических плиток, основанный на том, как далеко они находятся от камеры. Между краями двух плиток он будет скреплять эти края вместе, чтобы вы не получили зазоров или отверстий. Для углубленного изучения того, как это работает, прочитайте Быстрый рендеринг ландшафта с использованием геометрического MipMapping.
  • Дерево квадрантов(Quad Tree): вся структура ландшафта состоит из TerrainPatches(Клочков Ландшафта) (они содержат реальные сетки), они подобны листьям в древе квадрантов (TerrainQuad — Квадрант Ландшафта). TerrainQuad-ы дробятся на 4 части, до тех пор пока не будет достигнут минимальный размер, и тогда создается TerrainPatch, и в нём и располагается реальная сетка(mesh) геометрии. Это позволяет осуществлять быстрое отсечение ландшафта, который не виден.
  • Splatting: возможность рисовать несколько текстур на вашем ландшафте. Что здесь отличается от JME2, так это то, что все это делается в шейдере, больше нет проходов визуализации. Таким образом, он работает намного быстрее.
  • Редактирование в реальном времени: ландшафты TerraMonkey можно редактировать в jMonkeyEngine SDK, и вы можете изменять их в режиме реального времени, например, путем поднятия и опускания ландшафта.

Текущие Возможности:

  • Поддержка 16 splat текстур. Вы используете пользовательскую комбинацию Diffuse, Normal, Specular и Glow Maps.
  • GeoMipMapping: LodControl оптимизирует уровень детализации
  • Ландшафт может быть рандомизирован или создан из карты высот
  • Имеется редактор ландшафта в jMonkeyEngine SDK
  • Потоковая клетки ландшафта (т.е. Бесконечный ландшафт)

Планируемые Возможности:

  • Гидравлическая эрозия и процедурная генерация текстур
  • Отверстия: пещеры, скалы

Образцы кода

Geo Mip Mapping

terrain-lod-high-medium-low

Думаю ранее вы уже видели реализованный в играх GeoMipMapping. Это когда в месте ландшафта которое, располагается на определённом отдалении от игрока(камеры) применяется меньше полигонов чем у ближайшего окружения игрока, но по мере приближения игрока к этому месту, начинает использоваться все больше полигонов. Весь ландшафт разделен на клочки в виде клеток(grid), и каждая из них имеет свой собственный уровень детализации (LOD). Алгоритм GeoMipMapping просматривает каждый клочок и его соседей, чтобы определить, как визуализировать геометрию. Он будет прокладывать шов по краям отделяющим клочки с разными LOD.

GeoMipMapping часто приводит к тому, что вы видите переключение ландшафта от одного LOD к другому. TerraMonkey был разработан так, чтобы вы могли применять различные алгоритмы расчета LOD, и получали результат который будет лучше всего подходить для вашей игры. Вы можете сделать это с помощью интерфейса LodCalculator.

GeoMipMapping в TerraMonkey был разделен на несколько частей: Дерево квадрантов(Quad Tree) ландшафта и LODGeomap. Geomap имеет дело с фактическим алгоритмом LOD и сшиванием. Поэтому, если вам понадобится другая структура данных для вашей системы ландшафта, вы можете повторно использовать этот фрагмент кода. Дерево квадрантов (TerrainQuad и TerrainPatch) предоставляет средства для организации LODGeomap-ов, уведомляет их об изменении LOD своего соседа и обновляет геометрию при изменении LOD. Изменение LOD, оно делает, изменяя индексы буферов полос треугольников, поэтому всю геометрию не нужно повторно загружать на видеокарту. Если вы хотите узнать больше о том, как работает GeoMipMapping, прочтите: Быстрый рендеринг ландшафта с использованием геометрического MipMapping.

Дерево Квадрантов Ландшафт (Terrain Quad Tree)

TerraMonkey — это дерево квадрантов. Каждый узел это TerrainQuad, а каждый лист — TerrainPatch. TerrainQuad имеет либо 4 дочерних TerrainQuads, либо 4 дочерних TerrainPatches. TerrainPatch содержит сетку геометрий. Эта структура почти точно такая же, как система TerrainPage от JME2. Кроме того, каждый лист имеет ссылку на своих соседей, поэтому ему никогда не нужно проходить все древо, чтобы получить их.

Splatting Текстур

Когда вы накладываете текстуру на сетку, то вся сетка выглядит однообразно. Для больших сеток (например, ландшафтов), это нежелательно, потому что это выглядит очень скучно (весь ландшафт будет всей скалой, или всей травой, или всем песком). Splatting Текстур — это метод, который позволяет вам «нарисовать несколько текстур в виде одной комбинированной текстуры. Каждая из splat текстур имеет значение непрозрачности, поэтому вы можете определить, где она будет видимой в итоговой конечной текстуре.

Материалом по умолчанию для TerraMonkey является TerrainLighting.j3md. Этот материал объединяет несколько текстурных карт для создания окончательной пользовательской текстуры. Помните, Диффузные карты(Diffuse Maps) — это основные текстуры, которые определяют внешний вид; При необходимости, каждая Диффузная карта(Diffuse Map) может быть улучшена с помощью Карты Нормалей(Normal Map); Карты Прозрачности(Alpha Map) задают непрозрачность каждой используемой Diffuse Map (один цвет — красный, зеленый, синий или alpha — для непрозрачности одной Diffuse Map); Карты Свечения(Glow Map) и Карты Блеска(Specular Map) задают дополнительные эффекты.

Мы рекомендуем создавать и редактировать текстуры Splat для ландшафтов визуально в jMonkeyEngine SDK, а не делать это вручную. Если вам просто интересно, как работает плагин текстуры ландшафта SDK, или если вы действительно хотите сгенерировать материалы вручную, почитайте о деталях его реализации.

Вот названия свойств TerrainLighting.j3md:

  • 1-3 Карта Прозрачности(Alpha Map)
    • AlphaMap
    • AlphaMap_1
    • AlphaMap_2
  • 12 Диффузных карт(Diffuse Map) и/или Карт Нормалей(Normal Map) (либо по 6 пар и той и той, либо 12 независимых Диффузных карт)
    • DiffuseMap, DiffuseMap_0_scale, NormalMap
    • DiffuseMap_1, DiffuseMap_1_scale, NormalMap_1
    • DiffuseMap_2, DiffuseMap_2_scale, NormalMap_2
    • DiffuseMap_3, DiffuseMap_3_scale, NormalMap_3
    • DiffuseMap_4, DiffuseMap_4_scale, NormalMap_4
    • DiffuseMap_11, DiffuseMap_11_scale, NormalMap_11
  • Карты Освещения(Light map)
    • GlowMap
    • SpecularMap
DiffuseMap_0_scale — float значение (например, 1.0f); Вы должны задавать один масштаб на Диффузную карту.

OpenGL поддерживает максимум 16 sampler в любом заданном шейдере. Это означает, что вы можете использовать только подмножество свойств материала вместе со стандартным шейдером освещения ландшафта (TerrainLighting.j3md)!

Соблюдайте следующие ограничения:

  • 1-12 Diffuse Maps. Одна Diffuse Map как минимум!
  • 1-3 Alpha Maps. Для каждых 4 Diffuse Maps, нужна еще 1 Alpha Map!
  • 0-6 Normal Maps. Diffuse Maps и Normal Maps всегда идут в паре!
  • 0 или 1 Glow Map
  • 0 или 1 Specular Map.
  • Сумма всех используемых текстур должна быть 16 или меньше.

Вот некоторые общие примеры, что это означает:

  • 3 Alpha + 11 Diffuse + 1 Normal.
  • 3 Alpha + 11 Diffuse + 1 Glow.
  • 3 Alpha + 11 Diffuse + 1 Specular.
  • 3 Alpha + 10 Diffuse + 3 Normal.
  • 3 Alpha + 10 Diffuse + 1 Normal + 1 Glow + 1 Specular.
  • 2 Alpha + 8 Diffuse + 6 Normal.
  • 2 Alpha + 6 Diffuse + 6 Normal + 1 Glow + 1 Specular.
  • 1 Alpha + 3 Diffuse + 3 Normal + 1 Glow + 1 Specular (rest unused)

Вы можете рисовать карты Alpha, Diffuse, Glow и Specular в программах для рисования, например Photoshop. Задайте каждую splat текстуру на Alpha Map в красном, зеленом, синем или Alpha (=RGBA). Проект JmeTests, включенный в SDK, содержит некоторые файлы изображений, которые показывают, как это работает. В примерах изображений показана карта высот(heightmap) ландшафта рядом с ее Alpha Map (которая была подготовлена для 3-х Diffuse Maps) и одной простейшей парой Diffuse/Normal Map.

Пример кода: Terrain.j3md

В этом примере показано более простое описание материала Terrain.j3md, которое поддерживает только 1 Alpha Map, 3 Diffuse Maps, 3 Normal Maps и не поддерживает Фонг освещение. Это делает пример короче — TerrainLighting.j3md работает таким образом (список свойств материала см. Выше. Ссылки на расширенный пример кода см. Выше.)

Во-первых, мы загружаем наши текстуры и текстуру карты высот(heightmap) для ландшафта

// Создаём материал из Описания Материала Terrain
matRock = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
// Загружаем alpha map (для splat текстур)
matRock.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
// Загружаем изображение heightmap (для карты высот(heightmap) ландшафта)
Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
// Загружаем текстуры травы
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
matRock.setTexture("Tex1", grass);
matRock.setFloat("Tex1Scale", 64f);
// Загружаем текстуры почвы
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
dirt.setWrap(WrapMode.Repeat);
matRock.setTexture("Tex2", dirt);
matRock.setFloat("Tex2Scale", 32f);
// Загружаем текстуры травы
Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
rock.setWrap(WrapMode.Repeat);
matRock.setTexture("Tex3", rock);
matRock.setFloat("Tex3Scale", 128f);

Мы создаем карту высот из heightMapImage.

AbstractHeightMap heightmap = null;
heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f);
heightmap.load();

Затем мы создадим сам ландшафт.

  • Плитки ландшафта 65х65.
  • Общий размер ландшафта 513×513, но он легко может быть и до 1025×1025.
  • Он использует карту высот для генерации значений высоты.
terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
terrain.setMaterial(matRock);
terrain.setLocalScale(2f, 1f, 2f); // масштаб, чтобы сделать его менее крутым
List<Camera> cameras = new ArrayList<>();
cameras.add(getCamera());
TerrainLodControl control = new TerrainLodControl(terrain, cameras);
terrain.addControl(control);
rootNode.attachChild(terrain);
В качестве альтернативы карте высот на основе изображения, вы также можете создать Hill hightmap:

heightmap = new HillHeightMap(1025, 1000, 50, 100, (byte) 3);

Переведено для jmonkeyengine.ru, оригинал
Автор перевода: Andry

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

jMonkeyEngine.ru © 2017. Все права сохранены.