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

TerraMonkey — The jMonkeyEngine Terrain System

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

Обзор

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

  • GeoMipMapping: метод изменения уровня детализации (LOD) геометрических плиток, основанный на том, как далеко они находятся от камеры. Между краями двух плиток он будет скреплять эти края вместе, чтобы вы не получили зазоров или отверстий. Для углубленного изучения того, как это работает, прочитайте Быстрый рендеринг ландшафта с использованием геометрического MipMapping.
  • Дерево квадрантов(Quad Tree): вся структура ландшафта состоит из TerrainPatches (они содержат реальные сетки) как листья в дерево квадрантов (TerrainQuad). TerrainQuads разделяются на 4, пока не достигнут минимального размера, тогда создается TerrainPatch, и именно там живет реальная сетка геометрии. Это позволяет быстро отбирать ландшафт, который вы не видите.
  • 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. Это когда в месте местности которое, более отдаленное от игрока применяется меньше полигонов, но по мере приближения игрока к этому месту, используется все больше полигонов. Весь ландшафт разделен на сетку patche, и каждый из них имеет свой собственный уровень детализации (LOD). Алгоритм GeoMipMapping рассматривает каждый patche и его соседей, чтобы определить, как визуализировать геометрию. Он будет прокладывать шов покраям отделяющим patche с разными LOD.

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

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

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

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

Splatting Текстур

Когда вы накладываете текстуру на сетку, вся сетка выглядит одинаково. Для больших сеток (например, ландшафтов), это нежелательно, потому что это выглядит очень скучно (весь ландшафт будет всей скалой, или всей травой, или всем песком). Texture 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) для местности

// Create material from Terrain Material Definition
matRock = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
// Загрузка alpha map (для splat текстур)
matRock.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
// Загрузка heightmap image (для карты высот(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. Все права сохранены.