Render.ru

Анимация дерева и листвы.

Bollvax

Активный участник
Рейтинг
5
#1
Здравствуйте.
Очень нужна помощь.
Подскажите пожалуйста какими способом лучше анатомировать деревья и листву в Maya? Может есть уроки какие или плагины или еще что то. Каким способои обычно это делают. Мне необходимо более менее достижение реализма. Не топорную анимацию.
Был бы очень признателен всем ответившим. И за раннее спасибо.

Обновление сообщения автором
29.06.2012 в 00:49
Анимировать деревья*
 

Riper

Активный участник
Рейтинг
7
#2
Сталкивались с такой проблемой. Самый оптимальный по скорости\качеству выход был - вешать Lattice с партиклами в узлах, и воздействующий на них турбуленс с весами Goal'ов на них. Но надо пошаманить чтоб было более-менее реалистично. Плюс вешать по иерархии. 1 латтис на 1 ветку в идеале (зависит от дальности).
А вообще если понять суть проблемы - "кучу полигонов, изначально не предназначенных для анимации, нужно заанимировать, чтоб было похоже на листву и деревья" - конечно повергает в ступор))
Этим методом анимировались ветки на переднем плане в 1-й половине вот этого видео http://www.render.ru/gallery/show_work.php?work_id=82279&gal_rub=59&gal_add=discuss#work
 

Nurika

Пользователь сайта
Рейтинг
2
#3
http://www.creativecrash.com/maya/downloads/body%20paint/downloads/applications/translators/c/tree-simulation-script
 

iNOD

Активный участник
Рейтинг
18
#4
Я делаю анимацию веток и листвы при помощи джоинтов. Вот пример http://www.youtube.com/watch?v=pncwccf1sIk если интересно то могу объяснить подробнее но тут без использования скриптов не обойтись. На такой куст ушло времени 15-20 минут.
 

Skif

Администратор 3D галереи
Команда форума
Рейтинг
584
#5
оо класс.. объясни пожалуйста. интересно очень
 

Bollvax

Активный участник
Рейтинг
5
#6
Да конечно объясни очень интересно, думаю не только я буду очень благодарен.
 

iNOD

Активный участник
Рейтинг
18
#7
Завтра постараюсь выложить, мини урок) Сейчас не могу, так что извините.
 

Владимир Забелин

Активный участник
Рейтинг
17
#8
если паинт эффект + ncloth не нравится, то лет 10 назад был ролик про совершенно безумного зайца, фотографирующего ежиху в лесу+ урок по созданию листвы деревьев. там для анимации листвы использовалась довольно сложная техника - сами листики инстансировались, а для их ориентации использовались 2 системы частиц - для корешков и кончиков листов. Без мела там естественно не обошлось. название был что-то типа splash!!
 

iNOD

Активный участник
Рейтинг
18
#9
И так начнем.
1) Я создал березу при помощи PaintEffects (рис. 1).
2) Выделил точки последовательностью от низа вверх, по очереди, для создания джоинтов ствола дерева и запустил скрипт(рис. 2,3). Вот скрипт:
Код:
proc vrtJnt(){
string $selVerts[] = `ls -sl -flatten`;
string $vrts;
select -cl  ;
hilite;
for ($vrts in $selVerts)
    { 
    float $d[] = `xform -ws -q -t $vrts`;
    joint -p $d[0] $d[1] $d[2];
	}
}
vrtJnt;
3) Создаем еще дополнительные джоинты для веток (чем больше доп джоинтов тем лучше для анимации, но главное не переборщить) (рис. 4,5).
 

Вложения

iNOD

Активный участник
Рейтинг
18
#10
Да еще для удобного выделения точек я убираю сетку при помощи скрипта:
Код:
if (`displayPref -q -wsa`=="none")
displayPref -wsa "full";
else displayPref -wsa "none"
4) Делаем джоинты для как можно больше количества веток, но без фанатизма (рис. 6).
5) Выделяем основные ветки и скрываем, для удобства настройки доп веток (рис. 7).
6) IK Handle для такого кол веток быстрее всего делать через аутлайнер (если с зажатым шрифтом нажать на плюс, то откроется вся иерархия) (рис. 8,9).
7) Для удобства создания манипуляторов для доп веток прячем IK hendles, для ускорения процесса создания манипуляторов можно использовать скрипт Wizard_Controllers v1.0 модифицированный скрипт от Skif (рис. 10). Вот ссылка:
http://www.creativecrash.com/maya/downloads/scripts-plugins/character/c/wizard_controllers
 

Вложения

iNOD

Активный участник
Рейтинг
18
#11
8) Делаем Point Constrain хендлов к манипуляторам (рис. 11,12,13), для удобства лучше спрятать джоинты и показать Ik hendles.
9) Прячем доп джоинты и отображаем главные, и делаем с ними тоже самое (рис. 14).
10) Парентим доп джоинты к главным (горячая кнопка "p") (рис. 15).
 

Вложения

iNOD

Активный участник
Рейтинг
18
#12
11) Теперь парентим манипуляторы к джоинту к которому присоединены джоинты на которых влияет данный манипулятор (рис. 16,17).
12) Для проверки что не присоединили выделяем основной джоинт (рис. 18).
13) За тем парентим главные манипуляторы к основным джоинтам ветки (рис. 19).
14) Парентим основные манипуляторы веток к джоинтам основы дерева (рис. 20).
 

Вложения

iNOD

Активный участник
Рейтинг
18
#13
15) Для основы дерева создаем структуру на подобии как для позвоночника человека используя Ik spline handle tool (рис. 21).
16) Отключаем фильтры джоинтов и геометрии(геометрию необязательно), прячем также Ik handles, выделяем все манипуляторы кроме основы дерева (рис. 22).
17) Переключаем на первый кадр и жмем Shift+w ставим ключи для перемещения (рис. 22).
18) Переключаем на другой кадр, снова выделяем все манипуляторы и запускаем скрипт, задаем параметры и жмем move. За тем снова выделаем все манипуляторы и жмем Shift+w (рис. 23). Вот скрипт:
Код:
string $rndWin = `window -t "Random transform"`;
frameLayout -label "Values" -borderStyle "etchedIn";
columnLayout;
separator -style "none";
    floatSliderGrp -label "X" -field true -min 0 -max 360 vrrx;
    floatSliderGrp -label "Y" -field true -min 0 -max 360 vrry;
    floatSliderGrp -label "Z" -field true -min 0 -max 360 vrrz;
    setParent..;
	separator -style "none";
frameLayout -label "Select" -borderStyle "etchedIn";
columnLayout;
    separator -style "none";
    rowLayout -nc 4 -columnWidth3 40 40 40;    
    button -label "rotate" -c rdmRotate;
    button -label "scale" -c rdmScale;
    button -label "move" -c rdmMove;
    setParent..;
	separator -style "none";
showWindow;
global proc rdmRotate()
{
float $ivrrx = `floatSliderGrp -q -v vrrx`;
float $ivrry = `floatSliderGrp -q -v vrry`;
float $ivrrz = `floatSliderGrp -q -v vrrz`;
string $tranShape[] = `ls -sl`;
string $sTranShape;
for ($sTranShape in $tranShape)
{
select -r $sTranShape;
float $srvx = getAttr ($sTranShape + ".rotateX");
float $srvy = getAttr ($sTranShape + ".rotateY");
float $srvz = getAttr ($sTranShape + ".rotateZ");
float $rirry = rand (0, $ivrry);
float $rirrx = rand (0, $ivrrx);
float $rirrz = rand (0, $ivrrz);
if ($ivrrx==0 && $ivrry==0 && $ivrrz!=0)
{
rotate -r -os $srvx $srvy $rirrz;
print "1";
}
if ($ivrrx==0 && $ivrrz==0 && $ivrry!=0)
{
rotate -r -os $srvx $rirry $srvz;
print "2";
}
if ($ivrrz==0 && $ivrry==0 && $ivrrx!=0)
{
rotate -r -os $rirrx $srvy $srvz;
print "3";
}
if ($ivrrx==0 && $ivrry!=0 && $ivrrz!=0)
{
rotate -r -os $srvx $rirry $rirrz;
print "4";
}
if ($ivrry==0 && $ivrrx!=0 && $ivrrz!=0)
{
rotate -r -os $rirrx $srvy $rirrz;
print "5";
}
if ($ivrrz==0 && $ivrry!=0 && $ivrrx!=0)
{
rotate -r -os $rirrx $rirry $srvz;
print "6";
}
if ($ivrrx==$ivrrz && $ivrrx!=$ivrry && $ivrrz!=$ivrry)
{
rotate -r -os $rirry $rirry $rirry;
print "7";
}
if ($ivrrx==$ivrrz && $ivrry!=0)
{
rotate -r -os $rirrx $rirry $rirrx;
print "8";
}
if ($ivrrz!=0 && $ivrry!=0 && $ivrrx!=0 && $ivrrx!=$ivrrz)
{
rotate -r -os $rirrx $rirry $rirrz;
print "9";
}
}
}
global proc rdmScale()
{
float $ivrrx = `floatSliderGrp -q -v vrrx`;
float $ivrry = `floatSliderGrp -q -v vrry`;
float $ivrrz = `floatSliderGrp -q -v vrrz`;
float $nivrrx = $ivrrx/2;
float $nivrry = $ivrry/2;
float $nivrrz = $ivrrz/2;
string $tranShape[] = `ls -sl`;
string $sTranShape;
for ($sTranShape in $tranShape)
{
select -r $sTranShape;
float $ssvx = getAttr ($sTranShape + ".scaleX");
float $ssvy = getAttr ($sTranShape + ".scaleY");
float $ssvz = getAttr ($sTranShape + ".scaleZ");
float $rirsx = rand ($nivrrx, $ivrrx);
float $rirsy = rand ($nivrry, $ivrry);
float $rirsz = rand ($nivrrz, $ivrrz);
if ($ivrrx==0 && $ivrry==0 && $ivrrz!=0)
{
scale -r -os $ssvx $ssvy $rirsz;
print "1";
}
if ($ivrrx==0 && $ivrrz==0 && $ivrry!=0)
{
scale -r -os $ssvx $rirsy $ssvz;
print "2";
}
if ($ivrrz==0 && $ivrry==0 && $ivrrx!=0)
{
scale -r -os $rirsx $ssvy $ssvz;
print "3";
}
if ($ivrrx==0 && $ivrry!=0 && $ivrrz!=0)
{
scale -r -os $ssvx $rirsy $rirsz;
print "4";
}
if ($ivrry==0 && $ivrrx!=0 && $ivrrz!=0)
{
scale -r -os $rirsx $ssvy $rirsz;
print "5";
}
if ($ivrrz==0 && $ivrry!=0 && $ivrrx!=0)
{
scale -r -os $rirsx $rirsy $ssvz;
print "6";
}
if ($ivrrx==$ivrrz && $ivrrx!=$ivrry && $ivrrz!=$ivrry)
{
scale -r -os $rirsx $rirsy $rirsx;
print "7";
}
if ($ivrrx==$ivrry && $ivrrz==$ivrry && $ivrry!=0)
{
scale -r -os $rirsy $rirsy $rirsy;
print "8";
}
if ($ivrrz!=0 && $ivrry!=0 && $ivrrx!=0 && $ivrrx!=$ivrrz)
{
scale -r -os $rirsx $rirsy $rirsz;
print "9";
}
}
}
global proc rdmMove()
{
float $ivrrx = `floatSliderGrp -q -v vrrx`;
float $ivrry = `floatSliderGrp -q -v vrry`;
float $ivrrz = `floatSliderGrp -q -v vrrz`;
float $nivrrx = -1*$ivrrx;
float $nivrry = -1*$ivrry;
float $nivrrz = -1*$ivrrz;
string $tranShape[] = `ls -sl`;
string $sTranShape;
for ($sTranShape in $tranShape)
{
select -r $sTranShape;
float $rirty = rand ($nivrry, $ivrry);
float $rirtx = rand ($nivrrx, $ivrrx);
float $rirtz = rand ($nivrrz, $ivrrz);
if ($ivrrx==0 && $ivrry==0 && $ivrrz!=0)
{
move -r -os 0 0 $rirtz;
print "1";
}
if ($ivrrx==0 && $ivrrz==0 && $ivrry!=0)
{
move -r -os 0 $rirty 0;
print "2";
}
if ($ivrrz==0 && $ivrry==0 && $ivrrx!=0)
{
move -r -os $rirtx 0 0;
print "3";
}
if ($ivrrx==0 && $ivrry!=0 && $ivrrz!=0)
{
move -r -os 0 $rirty $rirtz;
print "4";
}
if ($ivrry==0 && $ivrrx!=0 && $ivrrz!=0)
{
move -r -os $rirtx 0 $rirtz;
print "5";
}
if ($ivrrz==0 && $ivrry!=0 && $ivrrx!=0)
{
move -r -os $rirtx $rirty 0;
print "6";
}
if ($ivrrx==$ivrrz && $ivrrx!=$ivrry && $ivrrz!=$ivrry)
{
move -r -os $rirtx $rirty $rirtx;
print "7";
}
if ($ivrrx==$ivrry && $ivrrz==$ivrry && $ivrry!=0)
{
move -r -os $rirty $rirty $rirty;
print "8";
}
if ($ivrrz!=0 && $ivrry!=0 && $ivrrx!=0 && $ivrrx!=$ivrrz)
{
move -r -os $rirtx $rirty $rirtz;
print "9";
}
}
}
19) Переключаем на первый кадр зажимаем колесико мышки на тайм слайдере и передвигаем на нужное кол кадров за второй ключ(что б была симетрия) и жмем Shift+w (рис. 24). P.S. колесико как бы копирует положение точек в текущем кадре и перемещает их по тайм слайдеру в нужную позицию.
20) Выделяем все манипуляторы и открываем Graph editor там выделяем все ключи анимации.
 

Вложения

iNOD

Активный участник
Рейтинг
18
#14
21) Выполняем действия как на рис. 26.
22) Не сбрасывая выделения с зажатым "Shift" выделяем манипуляторы весов как указано на рис. 27.
23) После того как выделили манипуляторы весов жмем кнопку "w" и зажимаем Shift+колесико мышки и двигаем слегка, увеличивая манипулятор (с целью смягчить анимацию, чтоб не было похоже на маятник часов) (рис. 28).
24) Приступаем к листве, выделяем меш листвы открываем UV Texture Editor, жмем F9 и выделяем основу листика (рис. 29).
25) Далее запускаем скрипт (так как будет созданы джоинты в основаниях листиков, нужно сократить количество выделенных точек, хотя можно и создать для каждого листика, все зависит от количества) (рис. 30). Вот скрипт:
Код:
string $rndWin = `window -t "Random Select Objects"`;
frameLayout -label "Values" -borderStyle "etchedIn";
columnLayout;
    intSliderGrp -label "Cycle" -field true -min 0 -max 70000 sV;  
    button -label "Select" -c rndmSlctObjct;    
showWindow;
global proc rndmSlctObjct()
{
int $c = `intSliderGrp -q -v sV`;
string $massObj[] = `ls -sl`;
string $smassObj;
int $cntObjct = 0;
int $idSctObj = 0;
for ($smassObj in $massObj)
{
$cntObjct++;
}
$idSctObj = rand (0, $cntObjct);
select -r $massObj[$idSctObj];
for ($i = 0; $i <= $c; $i++)
{
$idSctObj = rand (0, $cntObjct);
select -add $massObj[$idSctObj];
}
}
 

Вложения

iNOD

Активный участник
Рейтинг
18
#15
26) После исполнения скрипта выделенных точек стало меньше, запускайем первый скрипт который использовали для создания веток, получаеться что то странное но не пугаемся (рис. 31,32).
27) Выделяем основной джоинт и прописываем в командной строке строчку "Select -hi;" (рис. 33), можно эту команду повесить и на шелф, я лично часто пользуюсь ею.
28) Выделяем все джоинты и делаем почти тоже самое как и с манипуляторами веток только вместо move в скрипте Random Transform жмем rotate, а ключи ставим через Shift+e, так же для ключей анимации делаем те же манипуляции (рис. 34).
29) Зацыклюем анимацию Pre и Post infinity жмем Cycle (рис. 35).
 

Вложения

iNOD

Активный участник
Рейтинг
18
#16
30) Заново выделяем все джоинты листвы и запускаем скрипт(скрипт рандомно передвигает ключи анимации для каждого джоинта) (рис. 36). Вот скрипт:
Код:
{
string $bnLvs[] = `ls -sl`;
string $sbnLvs;
int $rTc;
for ($sbnLvs in $bnLvs)
{

$sbnLvs = substituteAllString($sbnLvs, "group1|", "");
$sbnLvs = substituteAllString($sbnLvs, "group2|", "");
$sbnLvs = substituteAllString($sbnLvs, "group3|", "");
$sbnLvs = substituteAllString($sbnLvs, "group4|", "");
$sbnLvs = substituteAllString($sbnLvs, "group5|", "");
$sbnLvs = substituteAllString($sbnLvs, "group6|", "");
$sbnLvs = substituteAllString($sbnLvs, "group7|", "");
$sbnLvs = substituteAllString($sbnLvs, "group8|", "");
$sbnLvs = substituteAllString($sbnLvs, "group9|", "");
$sbnLvs = substituteAllString($sbnLvs, "group10|", "");
$sbnLvs = substituteAllString($sbnLvs, "group11|", "");
$sbnLvs = substituteAllString($sbnLvs, "group12|", "");

$rTc = rand (1, 100);
keyframe -e -iub true -r -o over -tc $rTc ($sbnLvs + "_rotateX") ;
keyframe -e -iub true -r -o over -tc $rTc ($sbnLvs + "_rotateY") ;
keyframe -e -iub true -r -o over -tc $rTc ($sbnLvs + "_rotateZ") ;
}
}
31) Скрываем все кроме джоинтов веток и листвы, выделяем ближайшие джоинты листы к джоинтам веток и парентим их к веткам (рис. 37,38).
32) Для того что б было видно что незапарентнино можно покрасить основной джоинт ветки в цвет при помощи Wizard_Controllers v1.0 (рис. 39).
33) Остальные джоинты листвы я запарентил к основе дерева, чтоб увидеть разницу (рис. 40).
 

Вложения

iNOD

Активный участник
Рейтинг
18
#17
34) Выделяем манипуляторы веток, тоже зацикливаем анимацию Pre и Post infinity и рандомим ключи анимации при помощи другого скрипта (рис. 41,42,43). Вот скрипт:
Код:
{
string $bnLvs[] = `ls -sl`;
string $sbnLvs;
int $rTc;
for ($sbnLvs in $bnLvs)
{

$sbnLvs = substituteAllString($sbnLvs, "group1|", "");
$sbnLvs = substituteAllString($sbnLvs, "group2|", "");
$sbnLvs = substituteAllString($sbnLvs, "group3|", "");
$sbnLvs = substituteAllString($sbnLvs, "group4|", "");
$sbnLvs = substituteAllString($sbnLvs, "group5|", "");
$sbnLvs = substituteAllString($sbnLvs, "group6|", "");
$sbnLvs = substituteAllString($sbnLvs, "group7|", "");
$sbnLvs = substituteAllString($sbnLvs, "group8|", "");
$sbnLvs = substituteAllString($sbnLvs, "group9|", "");
$sbnLvs = substituteAllString($sbnLvs, "group10|", "");
$sbnLvs = substituteAllString($sbnLvs, "group11|", "");
$sbnLvs = substituteAllString($sbnLvs, "group12|", "");

$rTc = rand (1, 100);
keyframe -e -iub true -r -o over -tc $rTc ($sbnLvs + "_translateX") ;
keyframe -e -iub true -r -o over -tc $rTc ($sbnLvs + "_translateY") ;
keyframe -e -iub true -r -o over -tc $rTc ($sbnLvs + "_translateZ") ;
}
}
 

Вложения

iNOD

Активный участник
Рейтинг
18
#18
Вот и все) Вот какая анимация в результате получилась http://www.youtube.com/watch?v=wcIcDC109Mg нижняя часть дерева джоинты веток+джоинты листвы, верхняя часть просто джоинты листвы. Идеи реализации мои, потому могут быть не идеальны, так как информации по анимации растительности не нашел, и все придумывал методом проб и ошибок, хотя можно и анимировать пейнт эффект а потом конвертнуть в полигоны без чистки истории, но такую анимацыю не зациклить(циклическая анимация растительности полезна если, делается анимированный бинар прокси). Хочу еще добавить все скрипты мои кроме Wizard_Controllers v1.0, они немного не доделаны по этому извиняюсь, если что).
 

iNOD

Активный участник
Рейтинг
18
#19
Забыл один пункт, между 33 и 34 нужно заскинить меши на джоинты, иначе после пункта 34 джоинты не будут в том положении что и ветки.
 
Сверху