Создание модели для UDK в Maya
Внимание! Этот документ ещё не опубликован.
Автор: redbox
Здравствуйте.
Я хотел бы рассказать вам небольшой базовый урок о создании моделей для Unreal Engine 3.
Предварительные данные
Координатные оси
Maya Unreal
x - z z - x
| |
y y
Единицы измерения
Работайте всегда в сантиметрах, так проще жить, серьезно :)
Бюджет и оптимизация
Давайте посмотрим на следующую иллюстрацию:

На верхнем рисунке все ребра модели жесткие, на нижнем - мягкие.
Почему такая разница в количестве вертексов?
Потому что жесткие ребра добавляют вертексов. Один хард эдж +2 вертекса. Вобще они добавляют даже не вертексы а поля для записи дополнительной информации...
Теперь посмотрим такую иллюстрацию:

Здесь в обоих случаях все ребра мягкие, а ювишки сшиты.
Но, на первой по краю мы видим 8 вертексов, а на второй - 4. Вот вам и разница 16-12.
Разрезка на UV тоже добавляет вертексов. Одно разрезанное на UV ребро - +2 вертекса.
Плюс еще не стоит забывать про второй UV канал на лайтмапу, при неаккуратном исполнении он тоже потянет лишних байт. А если модель большая? Сколько дополнительной лишней инфы запишется в файл?
Кстати вы не увидите эти изменения в *.ase файле, они проявляются только после импорта в движок. Владельцы исходного кода возможно захотят ознакомится с FStaticMeshRenderData::Build и USkeletalMesh::CreateSkinningStreams для более детального ознакомления с проблемой.
Ни Maya ни 3DsMax не умеют показывать настоящее число вертексов, которое после импорта покажет движок. Может однажды кто то напишет какой то хороший и быстрый скрипт...
Да, возможно эти заморочки излишни, но если вы боретесь с лишними полигонами, наверно вы подумаете и об этой оптимизации.
Настройка сцены
Начнем с простого. Запускаем Maya, и настраиваем сцену
Up axis z
Units centimeter
fps ntsc 30
На этом настройка сцены еще не закончена. Давайте представим что мы в итоге хотим получить.
Это будет некий пропс, с лодом, коллизией, лайтмапой, и полным набором текстур(diffuse, normal, specular).
Открываем Hypershade и создаем в нем простой Phong, называем его как нибудь, я назвал Material. В вкладке 2DTextures находим и добавляем к материалу 4 ноды файлов:

Обзываем их соответственно - Diffuse, Normal, Specular и Lightmap.
(Если у вашей модели будут еще и элементы с альфа-каналом, то возможно стоит добавить ноду OpacityMask)
Теперь хитрым хаком мы обманем Майку. Зачем поймете потом.
Во вкладке OtherTextures выбираем единственную LayeredTexture. И теперь, через drug and drop по средней кнопке мыши, мапим Diffuse в ее input[0], а Lightmap в input[1].
Открываем свойства LayeredTexture в редакторе атрибутов и ставим BlendMode - None.
Далее, опять же через drug and drop по средней кнопке мыши, накидываем каждый файл на ваш материал.
LayeredTexture - Color
Normal - Other - в редакторе связей - OutColor - NormalCamera
Specular - SpecularColor
У вас получится такая конструкция:

Все, заготовка готова, сохраняемся :) Советую вам сохранить эту сцену в какой то отдельный файл как начальную для работы над такими объектами.
Создание объекта
Создаем наш простой объект.
Так как объект гениален и самодостаточен по своей сути, его совершенно не нужно переделывать.
Возможно вы даже нарисуете на него текстуры и назначите в соответсвующие ноды в материале...
Но мы ведь хотели еще лод, коллизию и лайтмапу!
Если вы знаете и понимаете что такое LOD, я думаю у вас не возникнет проблем с его созданием.
В анриле есть только один момент который нужно учитывать - по умолчанию, расстояния переключений лодов выставлены таким образом что первый не успевает исчезнуть до появления второго. Отсюда можно наблюдать эффект стробления. Старайтесь чтобы полигоны лодов не находились в одних плоскостях. Сдвигайте их немного, или масштабируйте сами модели.
Создать коллизию мы можем из этого же кубика. Дублируем его, обзываем UCX_01, и прячем в какой нибудь слой PhysL.
Для более сложных объектов правила создания коллизий не намного сложнее:
1 Именование UCX_*, где * - нумерация или имя английскими буквами.
2 Все элементы коллизии должны быть замкнутыми(без дыр) и выпуклыми(convex) поверхностями.
3 Нельзя объединять элементы коллизии в один меш, они просто должны быть выделены в момент экспорта меша, если вы делаете ExportSelection, или же просто присутствовать в сцене если вы экспортите ее полностью.
4 Нельзя чтобы элементы пересекались, они могут только примыкать.
5 Естественно пытайтесь избегать сложной коллизии.
6 На элементы коллизии должен быть назначен материал самого меша, или один из его материалов.
7 И одно от меня - никогда не делайте элементам коллизии отрицательный скейл. Никакой FreezeTransform вас не спасет. Элемент всегда будет испорчен после импорта в движок.
Создаем развертку для лайтмапы.
Открываем UVTextureEditor.
Выделяем все развертки, далее Polygons - Copy UVs to UV Set - Into New UV Set. По умолчанию он получит какое то имя, его не нужно изменять.

Сейчас мы с вами оказались на втором UV канале, где и будет располагаться лайтмапа. И как видите там нет текстуры.

С точки зрения описанных выше оптимизаций по количеству вертексов эта лайтмапа оптимальна, но неприемлема.
Почему так.
Например мы рассчитываем использовать на этом объекте лайтмапу размером 32х32.
Я пользуюсь пиксельмапами собственного производства. Ну могу и поделиться.
Pixelmap32
Спокойно! Это просто маленькая картинка. Сохраните ее себе и назначьте в Lightmap ноду материала.
После этого выделите вашу модель, Window - RelationshipEditors - UVLinking - UV-Centric.
В открывшемся редакторе отношений вы увидите вашу модель с ее каналами координат и материал с его нодами текстур.
Выберите второй канал UV и ноду Lightmap. Теперь пиксельмапа видна в UVTextureEditor'е.

Остальное не сложно. Сделайте отображение текстуры без фильтрации и включите снап к пикселям.
Переразложите ювишку максимально заполняя пространство.
Я сделал так:

Теперь проделываем эту операцию и с LOD'ом также.
Почему нельзя по-другому? Зачем обязательно четко по пиксельмапе?
Потому что лайтмапа прожигается по этим пикселям.
Если у вас шеллы ювишек не будут лежать четко по пикселам, и расстояние между ними будет меньше 2х пикселов, или они пересекутся, вы будете постоянно получать непонятные проблемы с освещением.
Какие то светлые или темные полосы и пятна там где их быть не должно. Изначально вам захочется решить проблему увеличением размера лайтмапы в самом движке, поставить не 32 а 128 например.
Да, это выход, но когда вы дойдете до сцен размером в несколько тысяч объектов, где вам не будет хватать лишних 5 мегабайт чтоб что то перестало постоянно мипмапиться, первым делом вы вспомните про лайтмапы.
Спасибо за внимание.
Отдельное спасибо Александру Макаренко за дополнительную информацию.
15 ноября 2010 (Обновление: 1 июня 2012)
Комментарии [0]
