伴隨著影視製作軟硬件技術的不斷發展,群組動畫作為一個新興的技術領域,這種技術可以模擬眾多角色的運動,在降低拍攝成本的同時,真實的再現了壯觀的場麵。群組動畫從技術的角度分為後期合成的群組動畫和全三維角色的群組動畫,早在70年代,好萊塢的導演們就開始試圖表現這些大場麵,那時的技術還不是很完善,對於群組動畫主要使用的是摳像,合成,拷貝的方法,對於鏡頭和導演意圖的表現都有很大的局限性。如《賓虛》等影片。在1992年,《蝙蝠俠回歸》首先使用了三維的群組動畫,影片《阿甘正傳》中的反越戰大規模示威也是如此。而如今,當我們看到《指環王》、《星戰》、《I robot》、《亞曆山大》、《最後的武士》等影片時,我們發現群組動畫已經成為大場麵表現的標誌之一,而且使用也越來越靈活,越來越複雜,場麵也越來越壯觀,對於劇情的推動起到了更好的作用。如圖1-1所示
後期群組動畫和三維群組動畫有著不同的表現效果,後期合成群組動畫主要使用在中景,全景,由於其中的演員都是由真人扮演, 場麵的真實性很高,特別是有時拍攝小全景時,還能清晰的看見演員的表演,場麵真實感人.三維群組動畫主要使用在表現千軍萬馬奔騰廝殺的大全景和航拍鏡頭中,場麵宏偉震撼,激動人心,在帶給觀眾激烈的視覺感觀刺激時將影片推向高潮,並給觀眾留下深刻難忘的印象。
由於群組的素材主要來自現場實拍,對前期拍攝的要求就比較高,,攝像機必須架設在三角架上,將攝像機鎖死,固定機位,同機位多次拍攝素材,後期製作時將演員摳出來,最終合成。我們以前多部影視劇中都有應用。如圖1-2所示。
三維角色的群組動畫相對於後期群組動畫有更大的***度和發揮空間,然而實現就要相對複雜的多,縱觀三維群組動畫的發展,主要可以分為兩大類:
1、 智能類(基於節點控製,可選擇行為的)或說是AI類
這一類的製作是基於節點控製、選擇的,也就是說在某種情況下,選擇某種行為。這種方式類似於人的基本活動,所以也就被現在很多的影片采用。它可以實現角色在複雜地麵的行走,而不會產生滑步,而且可以使角色具備動力學的特性,可以開發戰鬥,尋找,混合等多種複雜行為。由於這種製作方式是通過節點激活行為的方式來實現的,也就為事件製作的深度和廣度提供了可能。現在國際使用的這類商業製作軟件主要有以下幾種:Massive、Behavior和Aitool,但是這類製作有一定的難度,不但要有一定的編程技巧,還要能很好的規劃角色的行為流程。如圖1-3所示。
2、 非智能類(基於圖像或動作序列的)
非智能類的群組動畫,製作難度相對較低,如果體現千軍萬馬的效果,每個角色在畫麵中所占的相對像素就會小很多,利用流行的三維軟件的粒子係統,配合表達式的控製一樣能夠實現從簡單到複雜的群組動畫,其主要是以粒子序列的形勢表現,主要有SpriteParticle(序列粒子),InstanceParticle(實物粒子)兩大類。這類群組製作的優點就是難度較低,對於單體細節要求不高、行為可以很好的完成,如簡單飛鳥,人物行走等。雖然其行為的是基於序列的,默認情況下決定了行為的單一性。但是我們可以通過簡單的表達式來控製,使其富有變化,甚至按照我們的意願行動。
下麵我們就SpriteParticle(序列粒子),InstanceParticle(實物粒子)兩種粒子類型為例,分析他們的優缺點和複雜動作的實現。
1) SpriteParticle(序列粒子)的利用硬件渲染,渲染速度非常快,隻是前期的貼圖序列的製作比較繁瑣。如果是定機位或垂直於人物運動的方向推進,在場景中還要有近中遠角度的變化。在對單體取景的角度就要根據近遠的層次,分別去不同的角度序列。如圖1-4所示
2)我們這裏做個小的測試利用攝像機與地麵和每個角色粒子的夾角的變化,自動調用相應角度的序列。應用於定機位和垂直於人物運動的方向的推拉鏡頭。
(1)首先創建一個NURBS平麵,用比刷稍微刷一下,利用平麵發射例子;並將粒子goal在表麵上。如圖1-5所示。
(2)選擇粒子,把粒子類型轉為sprite,並執行Particles>Sprite Wizard,為sprite粒子再入序列楨貼圖。如圖1-6所示
[page]
(2)把我們利用五個攝像機渲染的走步動作序列串成一個序列,這裏走步是25楨一個循環,按照一定的順序,這裏我們是按照角度由大到小的順序,即第一段循環0-24,第二段,25-49,第三段50-74….以此類推,五個攝像機總的序列是0—124。如圖1-7所示
(3)然後就對粒子的運動和序列楨調用情況進行控製。這裏我們主要測試序列楨的分別調用,運動沒做過多的控製,隻是讓他們隨機的左右移動。自定義一批控製屬性,把sprite的一些需要的隱藏屬性調出來。如圖1-8所示
4)我們計算的原理是這樣的,創建兩個Locator,分別點約束與目標攝像機的攝像機位置和目標位置。利用兩個Locator的連線計算攝像機與水平方向的夾角,然後再計算攝像機與每個粒子的連線與水平方向的夾角。兩個夾角的差值就是每個粒子於畫麵中心的夾角,把這個夾角的範圍分為五份分別調入五個不同角度序列。如圖1-9
(5) 表達式如下:
Create expression(創建表達式)
//賦予離子生命值
particleShape1.lifespanPP=20;
//粒子生成後在nurbs表麵隨機分布
particleShape1.goalV=particleShape1.parentV;
particleShape1.goalU=particleShape1.parentU;
//賦予粒子大小隨機值
particleShape1.spriteScaleYPP=rand(3.1,3.5);
//將粒子隨即分為兩部分,一部分向左走,一部分向右走
particleShape1.Rand=rand(-1,1);
//一部分向右走,橫向縮放值等與縱向縮放值
if(particleShape1.Rand<0)
particleShape1.spriteScaleXPP=particleShape1.spriteScaleYPP;
//一部分向左走,當然走的姿勢相應要鏡像過來。
else
particleShape1.spriteScaleXPP=particleShape1.spriteScaleYPP*-1;
//麵片整體偏移到地麵之上,偏移量就是Y軸放縮的1/2。
particleShape1.goalOffset=<<0,particleShape1.spriteScaleYPP/2,0>>;
//隨即載入步伐循環的任意一個姿勢
particleShape1.orig=rand(24);
//獲取攝像機那邊的Locator的世界坐標值
Runtime expression:(運行表達式)
//粒子如果移動到nurbs平麵的邊緣,就消失掉。
if(particleShape1.goalU>0.98||particleShape1.goalU<0.02||particleShape1.goalV>0.98||particleShape1.goalV<0.02)
particleShape1.lifespanPP=0;
//粒子在表麵的移動速度,可以修改0.002這個數值來調整移動的快慢
particleShape1.goalU+=0.002*particleShape1.Rand;
//貼圖序列向前走
particleShape1.orig+=1;
//每到25的倍數楨就循環到0楨
particleShape1.orig%=25;
//以下部分為創建表達式與運行表達式都有的部分
vector $CL=<<CL.translateX,CL.translateY,CL.translateZ>>;
//獲取攝像機目標點的Locator的世界坐標值
vector $AL=<<AL.translateX,AL.translateY,AL.translateZ>>;
//獲取每個粒子的世界坐標值
vector $Pw=particleShape1.worldPosition;
//算出攝像機與目標點連線與Z軸的夾角
float $anglec=angle(<<0,0,1>>,($CL-$AL));
//算出攝像機與每個粒子連線與Z軸的夾角
float $anglep=angle(<<0,0,1>>,($CL-$Pw));
//獲得這個夾角的差值,並將這個範圍在-15—15度(測試得到)之間分為五份(0-4)
particleShape1.cyclenum=4*linstep(-15,15,rad_to_deg($anglec-$anglep));
//獲得這個範圍Id的整數部分。
int $num=trunc(particleShape1.cyclenum);
//根據這五部分的0-4,分別載入整個序列分為的五部分
switch($num)
{case 0:
//載入序列的第一部分
particleShape1.spriteNumPP=particleShape1.orig;
break;
case 1:
//載入序列的第二部分,與當前第一部分序列向後偏移25楨
particleShape1.spriteNumPP=particleShape1.orig+25;
break;
case 2:
//載入序列的第二部分,與當前第一部分序列向後偏移50楨
particleShape1.spriteNumPP=particleShape1.orig+50;
break;
case 3:
//載入序列的第二部分,與當前第一部分序列向後偏移75楨
particleShape1.spriteNumPP=particleShape1.orig+75;
break;
case 4:
//載入序列的第二部分,與當前第一部分序列向後偏移100楨
particleShape1.spriteNumPP=particleShape1.orig+100;
break;}
(6) 最終我們要實現的效果如圖1-11所示,粒子所帶數字為每套序列的ID號,即cyclenum得值。
(8)這是對此方法的初次嚐試,有什麼不足的地方,或者更加完善的思路與方法,還望各位多多指教。下一部分我們再來測試一下InstanceParticle(實物粒子)的動作控製,Instance肯定不會有什麼角度透視的問題,控製***度會更大,我們將測試幾個不同動作之間的切換,以及配合當前動作,如何影響粒子在表麵的移動速度。