Стены из бревна и немного MaxScript.
       

5cefd9701ab6780462102e550dcdf7e6.jpg

       
         Наверняка почти каждый, кто работает в профиле архитектурной визуализации, за свой рабочий срок сталкивался с возведением домов или помещений из бруса, бревна и т.п. Моделирование таких строений дело не сложное, а с текстурированием часто возникают проблемы. В реальной жизни нет одинаковых деревьев, поэтому и в 3D в погоне за фотореализмом следует избегать одинаковой фактуры на бревнах. Однако даже при использовании плагина Multitexture с 20-ю разными текстурами на модели обязательно всплывают несколько одинаковых бревен. Индивидуальный подход к каждому бревну может решить проблему, но думаю, в рамках даже одного помещения это будет весьма утомительно. А в случае с приличным домом это и вовсе невозможно. Ваш покорный слуга, вновь столкнувшись с моделингом деревянного дома, решил разобраться с вышеописанной проблемой. В этой статье хочу поделиться с вами небольшой автоматизацией.
 
       Прежде всего, необходимо поработать с самими моделями бревен, из которых вы собираетесь возводить дом. Модели могут быть любыми, вы можете использовать даже Boolean - суть требований от этого не изменится. В моем случае я на предварительном этапе создал всевозможные формы бревен и проделал с ними следующие операции:   
    1) на теле бревна и на торцах используются разные материалы, поэтому необходимо назначить разные id полигонам на соответствующих участках. Сделать это можно как отдельно на каждом бревне, так и на всех сразу, используя модификатор Edit Poly. Рис. 1-2.

c437c9aa9b645fb94876b23d6821db53.jpg

Рис. 1. ID боковых полигонов назначен 1

4171b45eb0224e3b43560fd8448137f0.jpg

Рис. 2. ID торцевых полигонов назначен 2

    2) Предварительно проверить локальную ориентацию моделей назначив модификатор UVW Map c типом мэппинга Cylindrical. Если Gizmo модификатора ложится корректно как на Рис. 3. то все в порядке. В принципе при стандартных вариантах моделирования бревен (из примитива Cylinder либо Circle + Extrude) модель будет иметь правильную ориентацию. Если вы все-таки умудрились получить иную ориентацию gizmo модификатора, то следует "поставить бревно вертикально" и применить Reset XForm из закладки Utilities.

46cbacc0bf2de3e89a06079aa9935f90.jpg

Рис. 3. Корректная ориентация Gizmo модификатора UVW Map

        Затем из подготовленных моделей выстраиваем по чертежам сечения дома, и собираем его воедино. С вашего позволения мы продолжим рассматривать статью на примере только 1 стены (Рис. 4), поскольку ни дизайнер ни заказчик не будут рады, что их проект фигурирует где-либо.

19ad088877741b40885535d6ceebccb2.jpg

Рис. 4. Пример стены.

        Поиск текстур так же достаточно утомительная процедура. Где взять текстуру развертки бревна?.. Обычная текстура дерева не подойдет - будет выглядеть не убедительно. Однако тут достаточно немного подумать и о эврика! Откуда берется такой материал как фанера? Правильно! Его спиливают с поверхности бревна! Поэтому вперед в гугл, ищем текстуру фанеры. Первые же результаты по тэгам "new plywood" часто ссылаются на старенький ресурс cgtextures com. Достаточно зарегистрироваться и вы получите доступ на скачивание фото высокого разрешения. Готовые текстуры не нужны, лучше сделать самому. Итак из всего многообразия я выбрал 3 фото, приглянувшиеся мне по фактуре. Рис. 5-7.

cb38a7d1d3bb333e0f2a6a22648ee74b.jpg

Рис. 5 Более спокойная и равномерная фактура.

6428f40c004400a4199e34208c6d2fdd.jpg

Рис. 6. Легкая фактура с узорами.

139863f32a9f4bd5da4ba6574ccd4b78.jpg

Рис. 7. Фактура с интересными узорами.

        После обработки в PS и сведения во одно изображение вышла неплохая текстура (Рис. 8), которую предстоит нарезать для уже упомянутого плагина Multitexture. Она намерено имеет такую вертикальную ориентацию, для дальнейшей беспроблемной проекции на бревна.

2276feadb0e863cb0c2e38843a6949b2.jpg

Рис 8. Основная текстура для Diffuse.

        Далее в PS я использую инструмент "Раскройка" для вырезки "плашек". Рис. 9.

 

7e55d90a1f7d5e8eb18e5e6f5c7bf4ac.jpg

Рис. 9.

        Чтобы автоматически сохранить все нарезки следует использовать команду Файл -> Сохранить для Web и устройств. Настройки опущу, посокольку они тут не существенны, просто выберите качество получше, и нажмите сохранить. В итоге в указанном месте PS создаст подкаталог images и разместит туда все файлы с пронумерованными именами(Рис. 10). Очень удобная вещь на мой взгляд.

515e174f7cd528ebcdbc54c3565e6ef8.jpg

Рис. 10. Нарезанные изображения.

        Для более хорошего эффекта каждое второе изображение следует перевернуть на 180 градусов или отразить по вертикали. Подредактировав исходную большую текстуру под каналы Reflect Glossiness и Bump сохраняем таким же образом отдельные плашки по тому же пути. В данном посте мы этот шаг пропустим.

        С текстурами для срезов бревен(торцов) тоже стоит заморочиться. Можно разумеется скачать с нашего любимого ресурса (3ddd) готовые, но лично мне они не совсем подошли. Хотелось чего-то по-мягче. В итоге пришлось выкраивать с плохого референса. Аналогично соединяем все в одно (Рис. 11)  для цветокоррекции и нарезаем на отдельные изображения.

c474fbeae3e68778a214633858db0c90.jpg

Рис. 11. Срезы бревен.

        Собственно все готово для кульминации. Создаем в сцене со срубом Multi/Sub-Object материал с 2-мя ID. Для ID 1 создаем простой матераиал(VrayMtl, CoronaMtl, ...) с картой Multitexture на канале Diffuse для которой указываем основные текстуры, для ID 2 аналогично, но выбираем торцевые текстуры. Рис. 12. Не забываем что в настройках MultiTexture следует выбирать не Material ID по умолчанию а Object.

dca60e3133fb8acd076c64713fa2ea3c.jpg

Рис. 12. Структура материала.(только Diffuse)

         Назначаем на наши бревна - Рис. 13. Результат предсказуемо плох.

adbe4dfd617b2bab395b96ae23784fd6.jpg

Рис. 13. Плохой или отсутствующий мэппинг.

        И вот тут нам на помощь приходит max script. Те кто с ним не знаком не стоит расстраивать и закрывать статью. Кода совсем чуть-чуть и он очень прозрачный. Гуру скриптов могут покритиковать)..

       Необходимо преобразовать все бревна в Editable Poly и убрать из сцены все кроме них. Первая операция по логике состоит в назначении всем объектам модификатора UVW Map с цилиндрической проекцией. Запускаем команду Run Script из главноего меню MAXScript. В появившееся окно MAXScript вводим код ниже. Т.к. я работал с бревном d = 280мм то скрипт будет выглядеть так:

/* AddModifier script */

m = uvwmap()  

m.maptype = 1 

m.cap = on 

m.length = 280  

m.width = 280 

m.height = 2695

for obj in $* do      

    addmodifier obj (copy m)

      Значение 2695 подобрано из расчета: 280*pi = k * 653 (длина короткой стороны текстуры в px). Вычислив k умножаем на 2000 (длинную строну текстуры в px) ~ 2695. Расчеты привел к тому что вы же будете использовать свои текстуры, поэтому это пригодится. Выполняем скрипт командой Ctrl + E. (или Tools->Evaluate All)        В результате выполнения скрипта всем бревнам назначится отдельно свой модификатор UVW Map, и наши бревна приобретут вид как на Рис. 14.

600c9839c14be3c8ae3081c06171782d.jpg

 Рис. 14. Бревна с цилиндрическим мэппингом.

        Мультитекстура во вьюпортах отображает 1 текстуру. Пробуем отрендерить. Плагин честно раскидал все 6 текстур, НО на лицо очень много повторяющихся элементов (Рис. 15).

54da6012e469426d238e77af03a48a23.jpg

Рис. 15. Повторяющиеся элементы.

        Да, можно увеличивать кол-во текстур, но это не наш метод! Лучшая идея это погонять Gizmo у модификаторов!! Смещать случайным образом по горизонтали и поворачивать вокруг бревна. В данном случае скрипт будет выглядеть так:

/* Randomize script */

for i = 1 to $* .count do 

(     

    obj = $*[i]     

    mdfr = obj.modifiers[1]     

    mdfr.gizmo.pos = [0, 0, (random -2700 2700)]     

    mdfr.gizmo.rotation = (quat 0 0 (random -0.99 0.99) 1)     

    ConvertTo obj Editable_Poly 

)

    Последняя команда перевода объекта в Editable Poly добавлена не случайно. Чуть позже опишу зачем*. Выполняем скрипт и вуаля!! Ни одного повторяющегося бревна! Рис. 16.

d9e7cc639395cfe521a78546911cf79f.jpg

Рис. 16. Нет повторяющихся бревен.

        Скрипт можно прогонять несколько раз пока результат не устроит. Казалось бы можно открывать шампанское, но нет. На торцах со спилами в круглых вырезах поплыл мэппинг (Рис. 17). Потому что тут боковая проекция цилиндричекой раскладки доминирует над верхом и низом. Придется назначать на торцевые полгоны свой планарный мэппинг.

e4783af7db900783eec2632747128c50.jpg

Рис. 17. Кривой мэпинг в выпилах.

        Но тут лень уже было шерстить справку по MaxScript и тут пригодился встроенный MacroRecoder. Следует запустить MAXScript Listener и Macro Recoder из главного меню MAXScript и вы увидите как все что вы делаете записывается в макрос. Этим результатом я и воспользовался. Соответственно получилась третья часть скрипта:

/* Planar mapping */

for obj in $* do  

(     

    select obj     

    subobjectLevel = 4     

    modPanel.setCurrentObject $.baseObject     

    $.EditablePoly.selectByMaterial 2     

    modPanel.addModToSelection (Uvwmap ()) ui:on     

    macros.run "Modifier Stack" "Convert_to_Poly" 

)

    Такие макросы имитирующие действия пользователя конечно выполняются дольше, но если кто-то улучшит - все будут признательны. *Т.к. тут исплользуется subLevel = 4(полигоны) то для этого скрипта все бревна заранее должны быть переведены в Editable Poly в предыдущем макросе. В результате перебора всех объектов получится то что надо. Рис. 18.

4947dd26a5ae360e89a659ea41bb5535.jpg

Рис. 18. Правильный мэппинг на торцах.

e893caafd0aad6c3513c21f8f48da7e4.jpg

 Рис. 19. Рендер.

        Теперь можно собрать все части скрипта в 1 и прогонять его для выстроенного сруба. Отмечу еще раз что в сцене ничего кроме бревен быть не должно. Поскольку сруб вероятнее всего является первым, что вы будете делать из проекта дома, то думаю эта ремарка не критична.

        Это пока все, чем хотел поделиться. Буду рад если кому-то пригодится.

бревнооцилинрованныйбруссруб

Комментарии (48)

+5
Rostyslav_Ha
спасибо, очень познавательно
+1
hazyaika
Хороший урок, правда еще не когда не делала с бревна но мало ли пригодится.
Спасибо!!!
+2
MastaMan
Спасибо за урок. Можно было бы сделать без Multitexture и упростить немного программную часть. Но в целом гуд, главное что это работает. Единственное замечу что вот так никто не делает:
1) $*[i]
2) macros.run "Modifier Stack" "Convert_to_Poly"
+2
color_bleed
Не удавалось получить доступ к объекту без индексации. А второй вариант я описал что это ленивый способ. Будем развиваться при необходимости.
+3
MastaMan
1) Первый вариант, лучше всего делать вот так:

for o in geometry do (code....)
for o in selecton do (code....)

Для индексации к примеру так selection или geometry не важно. Пример с selection

s = selection
for i in 1 to s.count do (print s[i])

2) Второй вариант:

ConvertToPoly o


Лучше всего изучать программирование, на других примерах.
Можешь посмотреть к примеру исходники моих скриптов, может поможет в изучении: http://3ddd.ru/forum/thread/show/blueprint_to_plane  http://3ddd.ru/forum/thread/show/smart_unfold_1  http://3ddd.ru/forum/thread/show/skript_prepare_model_3ddd 
+4
color_bleed
Я по образованию программист) и работаю инженером SmartPlant 3D. VBA, C#, Python. И в максе хочется рисовать а не кодить. А то везде одно и то же будет. Поэтому стараюсь обходить программирование тут.
+2
fila61
Проделана огромная работа. Главное, что все сделано правильно и точно, тут и не добавить больше нечего.
+1
novamen
спасибо
+1
AlexHappy
Круть! Текстуры брёвен особенно понравились! Благодарю!
+2
Legion-236
таких скриптов на "scriptspot.com" валом. Например: http://www.scriptspot.com/3ds-max/scripts/random-uvw-gizmotm 
+1
AlexHappy
Благодарю за наводку! Давно искал, но думал нет таких.
+1
color_bleed
В скрипте весь изюм, да, но статья не только же в скриптах.
По ссылке хорошая штука.
0
omforcemobile
Скриптов валом и дал ссылку на один, да смешно ничего не скажешь xD
+1
Sean
converttopoly obj чем не устроило?)

Кстати, на будущее, в циклах лучше не вычислять каунт, а делать это до цикла в переменную. Так он вычислится только 1 раз, а не при каждом проходе. Разумеется, если каунт постоянен.
Ещё имеет смысл перед выполнением скриптов с большим количеством действий переключать панель с модифай на криейт - будет чуть быстрее из-за отсутствия обновления интрефейса.
+1
sermen
Гы, а я всегда в рукопашную развертку бомбил, да и вроде быстро)
+4
DMed
А я думал будет итог как на первой картинке

В общем написано вроде правильно, но это как вырезать эталонные кубики для детей с точностью до миллионных миллиметра.
Обычный кубический мапинг и бесшовная текстура накидывается за секунду на весь сруб дома, и с расстояния камеры в 20м уже никто не увидит ничего
+ бревенчатые дома в архикаде делаются или подобных прогах. В максе извращенцы единичные дома только делают))
0
color_bleed
Несоответствие обложки содержимому уже тренд).. Но можно добиться и такого результата при желании.

У меня проекты таких домов обычно идут как с наружи так и внутри. Т.е. важен вид не только с 20 метров но и внутри, где такой мэппинг боксом будет выглядеть очень плохо.

И да, я их тех самых извращенцев) Категорические неприемлю рваную геометрию из архикада.
+1
Uraken
Уже много раз писали, что она не рваная при правильных настройках
+1
Komas
Спасибо за статью. Сперва подумал первая картинка это рендер и итог работы, а оказалось что это фотка с шатерстока) Но метод интересный а достижение реализма это уже вопрос техники. Сложнее всего раскидать текстуры
0
Женька
От же ж блин! И где вы были месяца 1,5 назад? Вот только рубленый дом закончили с коллегой моделить. В любом случае, спасибо.
+1
gapmad
За текстуры отдельное спасибо)))
0
KSABA
Да, и мне тоже год назад тутор был бы кстати)) Все равно спасибо!) 5+
+1
shizgara
А почему нельзя сразу в текстурах поставить рил ворлд размеры?
а вот "погонять гизмо" - это интересно.
+2
grdesigner
Я как то давным-давно поставил себе, уже не помню какую версию макса, главное что Design. В ней по-умолчанию в настройках bitmap'ы стояли World Coord. Сначала было неудобно, а сейчас неудобно когда вбиваешь размер в модификаторе. Особенно себя проявляет, когда один шейдер надо раскидать на кучу объектов.

Из неудобств пожалуй отмечу отображение шейдера в редакторе материалов. Чем больше текстура в реальных размерах, тем мельче она на примере и тем сложнее настроить мелочи. К примеру бамп. Необходимо рендерить, но с опытом уже интуитивно чувствуешь настройки. Но если бы можно было изменять масштаб отображения текстуры на шариках, было бы здорово.
+4
shizgara
Ну вот я к тому же. Там где часто повторяется текстура, бревна, кухни, корпусная мебель ид, проще поставить один раз рил ворлд. А отображение шейдера в редакторе можно настроить: правый клик на материале->options->render sample size
+1
grdesigner
Ух, ты. За sample size премного благодарен.
0
omforcemobile
Slate material editor, там размер шарика можно сделать огромный )
0
adamus
шикардос!
0
Юстас
Да, первым делом скачал текстуры! Спасибо!
0
d4m
Спасибо, интересно!
0
chilavek2007
Респект за текстуры!
0
sergo3d
Молодца! Хороший урок! +5
0
grdesigner
Автор, спасибо за урок. Я как раз из ленивых и если вижу повторяющиеся действия стараюсь их оптимизировать. За скрипты отдельная благодарность. Будем ковырять. )
0
ikslave
Офигенно! и как раз мне в тему) спасибо!
0
VladimirG
По любому автору плюс ! За проделанную работу ! Знатоки 3ds maxsа, конечно могут сделать это по своему, но миллион начинающих изучать 3d людей этого не знают и за это вам большое спасибо !
0
dedora
Спасибо. В закладки!
0
color_bleed
Спасибо за положительные отзывы!)
+1
mr.spoilt
"Откуда берется такой материал как фанера? Правильно! Его спиливают с поверхности бревна!"
Технология называется - лущение шпона.
0
UzMaster
Спасибо !!!
0
3ds-shaman
отличный урок, а то про кроликов я знаю, а вот такое первый раз встречаю, спасибо буду знать куда копать
0
belovicho
m.maptype = 1


Подскажите, а если брёвна в сечении квадрат, то что в типе m.maptype = 1 , какая цифра для Box
0
color_bleed
Порядок нумерации соответствует порядку проекций в параметрах модификатора UVWMap.
Вох проекция идет перед Cylindrical поэтому цифра будет 0. Cylindrical 1 и далее по порядку.
0
Svetlana_N
"Значение 2695 подобрано из расчета: 280*pi = k * 653 (длина короткой стороны текстуры в px). Вычислив k умножаем на 2000 (длинную строну текстуры в px) ~ 2695." - глубоко извиняюсь, но я вот все равно не поняла как вычислить свое значение m.height. Не могли бы Вы еще раз объяснить для особо одаренных. У меня бревно 260 мм, а текстура 667Х2000 мм.
0
Svetlana_N
Хотя, и таким числом все очень даже прилично. ))) Но все-таки хотелось бы разобраться.
0
color_bleed
https://yadi.sk/i/d1cmeIY3mFu9k
0
Ilia_P
Спасибо за урок! мне очень полезен, работаю с бревенчатыми домами.
К сожалению не работает данный скрипт:
/* Randomize script */
for i = 1 to $* .count do
(
obj = $*[i]
mdfr = obj.modifiers[1]
mdfr.gizmo.pos = [0, 0, (random -2700 2700)]
mdfr.gizmo.rotation = (quat 0 0 (random -0.99 0.99) 1)
ConvertTo obj Editable_Poly
)

3DsMax 2016 ругается:
-- Unknown property: "gizmo" in $Editable_Mesh:Box001 @ [25.000000,0.000000,0.000000]

к сожалению не смог решить это проблему помогите :)
0
Ilia_P
решено! был объект солнце на нем скрипт и тупил)
0
Potap2018
Отличная информация, спасибо огромное!!!)))