multiMap Shading Network


Это старая статья от конца 2006го года. Так как я закрываю сайт где она до сих пор лежала, решил добавить задним числом сюда.


Часть I. Описание основной задачи
Часть II. Пример наложения колор мапов
Часть III. Пример наложения дисплейсментов
Часть IV. Примечания

– Скачать скрипт multiMap –


Часть I. Описание основной задачи

Фундаментальная идея – накладывать на определенные части цельного меша отдельные текстуры. Т.е. есть у нас, к примеру, персонаж – один большой меш – и хочется положить на лицо ему отдельную большую карту дисплейсмента, на голову – поменьше, на тело еще одну, на руки, на ноги… Или может быть положить отдельный 4к дисплейсмент на губы, если они будут крупно в кадре.

Как это сделать – можно придумать ряд вариантов, но по тем или иным причинам почти все оказываются малоприменимыми. Самый лучший способ, который я нашел – отделить маппинги нужных областей, растянуть их на весь UV квадрат и смещать по +U – т.е. не умещать все в стандартном 0-1 UV квадрате, а в соседние:

После этого, такие программы как zBrush и Mudbox позволяют скульптить деформации/детали и генерить отдельные карты дисплейсмента для каждого такого квадрата:

И можно больше особо не переживать, что не хватает пространства в 4к карте чтобы сделать трещинки на губах персонажа. Но встает вопрос – как это теперь применять 🙂

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

Все дальнейшее я объясню на двух конкретных примерах.


Часть II. Пример наложения колор мапов

Задача: покрыть цельную модель коридора отдельными текстурами, безшовно и с определенным расположением элементов. Коридор для кино, т.е. по высоте текстура должна быть около 1556 пикселов. Округляем до следующего “текстурного” разрешения – 2048. Коридор в длину в 10 раз больше, чем в высоту. Т.е. текстура получается должна быть 20480х2048 🙂 Что, очевидно, сделать будет проблематично. Можно разбить коридор на отдельные секции, возится со стопкой шейдеров, а потом скрывать какие-нить неточности рендера на стыках. Можно придумать еще что-то, но описанный выше метод мне кажется удобнее.

1. Имеем стенку коридора (супер хай-рез :))

2. Хотим наложить на него текстуры следующим образом – чтобы текстура wall затайлилась по все длине, а door и painting наложить сверху по альфе в нужные места:

3. Маппим его равномерно по вышеописанному методу – по высоте на 0-1 V, а по U он получается 0-10 – на десять квадратов +U ложится:

4. Запускаем скрипт MEL командой:

multiMap;

и получаем интерфейс (написанный Денисом ‘0-1’ Рыбаковым)

5. Клеточки наверху – представляют 10 UV квадратов – от 0 до +10 по U (эти велечины фиксированные для простоты скрипта, поэтому маппинг надо располагать только в них). В них надо навалить нужные текстуры. Причем самая левая текстура автоматически будет сделана тайлящейся, остальные на нее наложатся. Выделяем ноду нужно текстуры и кликаем в желаемую клетку – свотч текстуры появится в ней. Таким образом, собираем свой коридор (если нажать на “Clear all” – все клеточки опустошатся)

6. Выделяем объект коридора и нажимаем GO!!! Первое что скрипт сделает – уменьшит весь маппинг в 10 раз относительно 0х0

7. Если маппинг сделан как описано выше – в 0-10 +U квадратах, он уместится в соответствующее кол-во клеток в нижнем ряду стандартного 0-1 квадрата:

8. Затем он создаст нетворк, в котором самая левая текстура (wall) будет нижним тайлящимся слоем, а все остальные (door и painting) наложены сверху в соответсвующих местах. Сборка слоев осуществляется в layeredShader в режиме layeredTexture (потому что нода layeredTexture не сохраняет float point текстур – 32-битные дисплейсменты собирать в нее нельзя, а layeredShader сохраняет). Плейсменты будут созданы специальные, их значения настроены так, чтобы попадать в соответствующие клетки маппинга. Если одна и та же текстура используется больше одного раза – для нее будет создан дубликат:

9. Полученный layeredShader (multiLayer1 – хоть он и шейдер, но лежать будет в закладке Textures гипершейда) можно назначать на нужный канал основного шейдера и рендерить коридор:

10. К примеру, нам не понравилось расположение элементов, можем просто перещелкать клетки в GUI скрипта (если не выделить ничего и нажать на клетку – она опустошится)

11. …и нажать GO!!! снова – сетка автоматически очистится и пересоздастся – все исходящие из multiLayer1 связи будут сохранены. К сожалению, уменьшенные и смещенные ранее текстуры перегенерят свои свотчи в черные с маленькими квадратиками – смотреть их станет неудобно, но малой кровью это исправить не удалось – либо переназначать, ориентируясь по именам, либо вначале нажать кнопку “Delete latest multiMap network”, которая очистит всю сетку, сделанную в прошлый раз (разумеется, коннекты multiLayer1 пропадут)

12. Изменения отдельных элементов можно происводить вручную стандартными методами – вводя значения плейсмент нод. К примеру, уменьшить одну из дверей и увеличить одну из картин:

Таким образом можно маппить до десяти разных текстур. При желании, можно сделать 10 и еще 10 других и совмещать полученные multiLayer’ы вместе.


Часть III. Пример наложения дисплейсментов

1. В целом, суть та же самая. Имеем обычный плейн:

2. Делаем ему мультиМаппинг на 6 UV квадратов:

3. В zBrush делаем скульптинг и генерим карты дисплейсмента для каждого UV квадрата:

4. Запускаем multiMap и назначаем соответствующие текстуры на квадраты с соответствующим маппингом:

5. Выделяем плейн, нажимаем GO!!! Мапинг уменьшается в 10 раз:

6. Заполняет соответствующие 6 клеток нижнего ряда стандартного 0-1 UV квадрата:

7. Особенность наложения дисплейсментов в том, что нужно отключить тайлинг левой текстуры. Это можно сделать вручную в плейсмент ее ноде:

8. Построенный multiLayer1 втыкаем в luminance ноду и назначаем как дисплейсмент основному шейдеру:

9. Рендерим объект с дисплейсментом:

Я специально на всех швах нарисовал волнистые линии – чтобы увидеть разрывы или несоответствия. Их, как видно, нету – 6 дисплейсментов стыкуются бесшовно (это еще дело настроек экспорта в zBrush). Справа внизу артефакт – это от открытых краев при смуфе в zBrush – к нашему делу не относится 🙂


Часть IV. Примечания

Можно так же построить сетку и не сжимая маппинг объекта в 10 раз, но тогда требуются дополнительные ноды – и довольно много. Вот пример сетки для того же самого коридора:

[+] с объектом ничего не происходит совершенно, маппинг его никак не изменяется

[+] свотчи всегда остаются крупными 🙂

[-] много всяких дополнительных нод (в основном для правильного маппинга текстур по альфа каналу и т.п.), громоздкость

Как бы то ни было, прилагаю на всякий случай вариант скрипта для создания таких сеток – скачать

Leave a Reply