Растительность в Unreal Engine 4
В Unreal Engine 4 по умолчанию есть встроенный инструмент для работы с растительностью под названием Foliage tool. Он добавляет клонированные статические меши (в более общем смысле слова – бесскелетные модели). Каждый ассет с растительностью можно добавить на карту тысячи раз с разными настройками поворота, расположения и т. д. для всех экземпляров.
При относительно небольших (до 10 000 экземпляров) и простых (менее 100 полигонов) ассетах всё будет отлично работать даже с тенью и хорошим освещением растений. Но нужно разумно настроить расстояние отсечения, чтобы графические аппаратные средства не пытались отобразить все 10 000 экземпляров сразу.
Впрочем, для относительно больших скоплений растительности (к примеру, целых лесов) это может стать проблемой.
Рассмотрим пример из моей игры. На севере карты – большой лес, игрок может войти в него с юга. Всё, что находится за пределами южной стороны леса, – это неигровая зона. Но ее всё равно нужно рендерить, чтобы создать у игрока впечатление обширного и необъятного леса.
Если бы мы решили рендерить весь лес, даже при использовании низкополигональных моделей деревьев это понизило бы производительность на слабых компьютерах.
Именно в этом случае на помощь приходят билборды.
Билборд это что-то из области рекламы?
Unreal Engine 4 в базовой комплектации поддерживает компонент Billboard Material Component. Он хорошо подходит для работы с единичными или немногочисленными мешами в уровне, как показано на примере выше. К сожалению, его нельзя использовать для инструмента Foliage tool, который поддерживает только размещение статических мешей. Чтобы использовать компонент Billboard Component, он должен находиться внутри класса Actor, который не поддерживается данным инструментом.
Нужно сделать собственный Billboard Material. О том, как это сделать, можно почитать в документации по ссылке здесь, в разделе о стилизованном рендеринге (некоторые не сразу находят нужную информацию, потому рекомендую читать внимательнее).
Я не буду пересказывать этот документ. Взамен я добавлю скриншот моего материала, созданного по документации, и расскажу, как использовать его в игре.
Для начала импортируйте простые 2D текстуры, которые будут выполнять роль спрайта с билбордом. С этой целью я сделал скриншоты модели дерева на прозрачном фоне. Если смотреть с определенного расстояния, они очень похожи на высокополигональные модели.
Важно оставить немного разнообразия: я создал 4 варианта одного дерева, чтобы модели не выглядели одинаково.
Подготовка материала
Следующий шаг – создать материал, который будет отвечать за то, чтобы вершины статического меша были всегда обращены к камере. В качестве статического меша возьмем четырехугольник, образованный двумя треугольниками (об этом немного позже).
Перейдите в панель Content Browser, кликните правой кнопкой мышки и создайте новый Material.
Выберите следующие настройки:
- Blend Mode: Masked;
- Shading Model: Unlit;
- галочка напротив параметра Two Sided.
Затем можете поместить узлы на графическую панель материала.
Сделаем несколько важных уточнений. Материал настраивает положение вершин так, чтобы они были повернуты к камере. За счет привязанных к World Position Offset узлов материал настраивает положение своих вершин так, чтобы они были повернуты к камере.
Узел 'Custom' содержит внутри секции, отвечающей за эффекты билборда, специальный HLSL-код. Он нужен для вычисления правильного поворота четырехугольника. Параметры этого узла выглядят так: напротив 'Inputs' нужно выбрать одно значение и назвать его 'In', а напротив ‘Output Type’ – CMOT Float 2. В документации это описано иначе, но там неправильные названия параметров:
float2 output;
output = atan2 (In.y,In.x);
return (output);
Узлы, привязанные к PivotPosition, отвечают за то, чтобы прямоугольник переносился в трехмерное пространство в соответствии с координатами и вращался вокруг исходной точки.
Но этот материал не предназначен для прямого использования. Текстура была преобразована в Material Parameter, который будут использовать экземпляры материала.
После сохранения материала кликните по нему правой кнопкой на панели Content Browser и сделайте несколько экземпляров. Каждый из них должен использовать правильную текстуру вашего билборда. Так код не будет дублироваться, а ресурсы будут расходоваться эффективнее.
Определив материал, загрузим в Unreal Engine 4 простой прямоугольник, который будет использоваться как статический меш для Foliage tool.
Создание и загрузка меша
Для модели билборда нужен только прямоугольник, состоящий из двух треугольников. Создайте такой ассет с помощью программы Blender либо загрузите тот, который использовал я. Он доступен для скачивания по ссылке, смело используйте его в любых проектах.
Возможно, при импорте треугольника вам придется настроить его перенос и поворот, чтобы он изначально был обращен к камере и располагался на поверхности. Если этого не сделать, материал повернется к камере боком или перевернется вверх ногами (или то и другое сразу) и будет неправильно переносить свое положение в трехмерное пространство. В результате материал всегда будет повернут в неверном направлении.
Я использовал для четырехугольника следующие настройки:
- Roll: 270 градусов.
- Pitch: 180 градусов.
- Yaw: 0 градусов.
- Import Uniform Scale: Настройте в соответствии с размером вашей карты, сам по себе четырехугольник достаточно большой.
- Import translation, Z axis: Настройте в соответствии с ландшафтом. Я выставил на 190 единиц.
По завершении импорта дайте четырехугольнику имя (я свой назвал TreeBillboard_Quad_1) и присвойте четырехугольник материалу билборда.
Теоретически мы уже могли бы поместить четырехугольник на карту и убедиться, что при движении камеры он всегда повернут к зрителю. Но разумнее будет перетащить этот статический меш в Foliage tool и поработать над его размещением:
Добавляя меш в Foliage tool, убедитесь, что опции Align to Normal и Random Yaw отключены: они поворачивают меш и нарушают эффект материала.
Этот меш всегда нужно располагать за пределами игровой зоны, где игрок не сможет к нему приблизиться или обойти, иначе вся иллюзия нарушится, и это будет смотреться, мягко говоря, плохо.
Когда вы добавите несколько тысяч таких деревьев, получится лес. Качество результата напрямую зависит от качества изначальных текстур:
Внешний вид
Обратите внимание: в своей игре я использую модель дерева низкого качества – только такую можно было найти в открытом доступе на сайте OpenGameArt. Повторюсь, результат зависит от качества и детализации меша, по которому создаются изображения, а также от разрешения этих изображений.
Ниже приведены для сравнения деревья с тенью и освещением и простые неосвещенные билборды:
А дальше показано, как выглядят эти деревья в том разрешении и размере, в котором лучше всего подходят для отображения. На изображении представлены как меши (ближе), так и билборды (дальше). На первый взгляд их трудно различить, а с более качественными мешами и изображениями это будет смотреться еще эффектнее:
Производительность
Поскольку мы рисуем только 2 треугольника для каждого дерева, производительность при таком подходе более чем приемлемая для современных компьютеров. Мне удалось заполнить деревьями всю карту без заметного снижения производительности средней видеокарты (AMD R9 270X). Метод также отлично подходит для работы с тростником, травой или другими мелкими растениями. Игрок не заметит, что они плоские, даже если подойдет ближе.
К билбордам непросто применить освещение или тень, поэтому в моей игре у них нет тени.
Игрок вряд ли заметит это с большого расстояния, но если он подойдет достаточно близко, недостаток обнаружится.
Правда, производительность в данном случае неидеальна. Узел 'Custom', который мы используем для материала, не позволяет движку оптимизировать шейдер. Сейчас это не играет роли, но у вас может быть по-другому. Если сомневаетесь, воспользуйтесь профайлером.
Альтернативы
Есть и другой подход – применять низкополигональные LOD-цепочки, которые генерируются с помощью таких инструментов, как Simplygon или Meshlab. В качестве растительности можно также использовать импостеры. А еще лучше совместить 3 подхода, используя высокополигональную модель дерева (например, с speedtree.com) и наименее детализированную модель в вашей LOD-цепочке. Так вы экономите ресурсы. Когда дерево находится далеко, оно не отличается от плоского спрайта по части детализации и теней. Поэтому необязательно прорисовывать его полностью.
Вывод
Надеюсь, эта статья принесет пользу вашей игре и позволит не тратить целое состояние на дорогостоящие видеокарты. Есть много способов рендерить растительность, и это только один из них.
Комментарии (0)