李安導演的《少年 Pi 的奇幻漂流》有許多令人印象深刻的特效畫面,這是怎麼做到的?T客邦取得《有物報告》的同意,轉載該網站一篇值得閱讀的文章,告訴大家「Procedural Modeling 程序性產生」如何協助藝術家、設計師產生令人驚豔的奇幻效果。
李安征服刁鑽紐約客
19日晚上筆者有幸參加李安導演的新片《少年 Pi 的奇幻漂流》紐約口碑場試映會(screening),地點在紐約42街附近的 AMC 影院。筆者還未到戲院,遠遠的就已經看排隊人潮了。現場約有三百多人,各種族裔齊聚一堂。
電影結束後,筆者豎耳偷聽,反映普遍都不錯,也有許多人散場後留在戲院小組討論了起來。看來台灣之光李安導演又再次征服刁鑽挑嘴的紐約客。
▲紐約 AMC 戲院。圖片來源:wallyg
當然電影本身沒讓我失望。其中的唯美畫面,似乎將時間定格似的,一幅幅深植腦海。
筆者不知道李安是否參與了美術設定這個環節。但在遊戲製作的時候,會有所謂 Art Director 來確保遊戲的美術設計從始至終一貫。通常 Art director 會有一本所謂的 Art Bible,供遊戲製作時的美術風格創作依據。根據李安的說法,他本人花了一年的時間將整個漂流歷程畫成動畫,所以我想導演的美學修養多少會展現在《少年 Pi 》的美術設定中。
沒有 Procedural Modeling,少年 Pi 就無法奇幻漂流
除了唯美的畫面之外,電影中大量應用「程序性產生」( procedural modeling)的特殊效果場面,更是讓筆者印象深刻。尤其是鯨魚躍出水面、以及主角望著海中沉思的這幾個橋段。
看到鯨魚躍出水面時,伴隨著數不清的水花、許多相似的 3D 模型組合成大量的幾何圖形交疊,讀者會不會想,這到底是如何辦到的?
通常電影中需要大量類似模型,例如「一千棵樹的背景」時,藝術家不會一株一株的建立模型,而會選擇讓電腦去做這樣具有高度重複性的工作。也就是說利用某種溝通的方式,讓電腦能夠理解你的意圖,之後讓電腦負責 heavy lifting,這樣的方法稱為 Procedural Modeling。
如下圖《少年 Pi 》的電影截圖中,有許多形狀特異的浮游生物與魚類水母等。如果藝術家認真的手動的畫,那我們可能要等到2015年才看得到這部電影了。
▲《少年 Pi 的奇幻漂流》場景中大量型態類似的海中生物,是如何產生的呢?圖片來源:apnatimepass.com
Procedural Modeling 幫藝術家節省了大量寶貴的時間
其實 procedural modeling 是一個概稱,舉凡任何利用數學(algorithm)與規則所產生出來的模型都可以納入此範疇。如用來產生樹木模型的 L System。
目前市面上每個 3D application 都可藉由 C 語言、Python 語言或是其他程式語言來完成 procedural modeling 的任務,當然最常見的 Maya 也不例外。Maya 有自己的 scripting language 叫做 MEL(Maya Embedded Language),如果筆者沒記錯的話,Maya 在2008的版本之後開始支援 Python。
MEL 語言初探
筆者想跟讀者分享一段簡單的 MEL,如下:(編按:雖然主編也不懂程式碼,但不影響對整篇,特別是結語的理解)
for($x = 0; $x < 8; $x++) {
for($y = 0; $y < 8; $y++) {
if($x > 2 && $x < 5 ||
$y > 2 && $y < 5)
{
// leave a “hole”
}
else
{
sphere -r 0.25;
move (0.5 * $x) (0.5 * $y) 0;
}
}
}
解釋一下:
For 是 MEL 中的迴圈,錢的符號$是 MEL 要宣告任何變數之前一定要加上去的,$x++ 的意思是 $x+1,&& 是 and 的意思,||的意思則是 or。
所以上列的 MEL 的意思是:如果 x 小於8,就往上加1,x 從0開始。接下來如 y 小於8,就往上加1,y 從0開始。
接下來是一個寫程式常看到的 if 與 else 條件式,解釋如下:承接上述的迴圈,如果 x 大於2小於5,或是 y 大於2小於5,則,創造一個半徑為0.25單位的圓,然後朝座標xyz = (0.5乘 $x) (0.5 乘 $y) 0 移動。在此的() 是小括號, {} 為大括號。因為 MEL 是先乘除後加減,先做小括號再做大括號。
下圖是這段簡單的 MEL 在 Maya 執行的結果: (編按:哪裡簡單?)
▲利用MEL所產生的 procedural modeling 範例。圖片來源:Chi-Feng。
跟上述 MEL 對照,共產生64個半徑0.25的圓形。為何每個圓形會如此整齊排列?讀者可以看最後一行「move (0.5 * $x) (0.5 * $y) 0」。因為半徑是0.25,所以直徑會是0.5,因此無論有多少個圓形,他們之間的距離都會是0.5單位,肩並肩整齊的排列著。至於中間為什麼會有空隙,那是因為「if($x > 2 && $x < 5 ||$y > 2 && $y < 5) 」條件式的關係,所以在x與y的3和 x與y的6之間會有空隙存在。
接下來,如果我想要在 Z 座標搞出點圓形來(上面的 MEL 只會在 x 與 y 座標上產生圓形),該如何做呢?我想聰明的讀者應該想到了吧?(編按:….)只要加上「for($z = 0; $z < 8; $z++)」在迴圈裡,與這一行:
if($x > 2 && $x < 5 ||$y > 2 && $y < 5 || $z > && $ < 5)
就會得到下圖的結果:
▲在 z 座標加上圓球進而產生立體感。圖片來源:Chi-Feng。
圖片是用非常早之前介紹過的 ambient occlusion 的渲染方式渲染出來的,讀者可以看出 z 座標放上圓球後,整個立體感就出現了。
Procedural modeling 是程式設計師向自然取經
看到這,讀者或許會問,這一段 MEL 似乎離《少年 Pi》中的奇幻特效還有點距離?當然圓形跟魚的形狀是差很多的,上述那段 MEL 充其量也只是一個開頭,只是產生出一個非常簡單的 procedural model。
但至少讀者可以體會到使用 MEL 所帶來的方便。請試著想,我如果要手動產生8*8*8共512個圓形並整齊排列,要花多少時間?如果使用 MEL 的方式在瞬間產生大量的圓形,並且可以隨時修改,這種效率正是電影特效製作中最需要的。
如果留心看看自然界,上天已經隱藏的許多絕妙的 procedural model 在我們身邊了。讀者應該都看過向日葵吧?向日葵 flower core 的部分,如果讀者仔細觀察,您會看到一幅上帝的傑作。
▲向日葵 core 的排列,隱藏了一系列數學計算。圖片來源:sunflowerexperiment.com。
向日葵花的排列,非常具有規律與美感,由中心像花瓣一樣四散出去。類似這樣排列的圖樣,在數學上稱為「費馬的螺旋」(Fermat’s spiral),而其中最適合描述向日葵花的是一種叫 Polar system 的座標系統。向日葵的wikipedia有對向日葵核心排列的圖樣更詳盡的解釋,讀者可參考了解筆者下述的 MEL。
筆者參考 Polar system 的三個核心部分:
寫出了下列的 MEL:
for ($i =0; $i <=200; $i++){
float $currentAngle = $i * 137.5;
float $radius = 15 * sqrt($i);
float $newY = -1 * $radius * sin($currentAngle);
float $newX = $radius * cos($currentAngle);
sphere;
duplicate;
scale (1+$i*0.2) (1+$i*0.2) (1+$i*0.1);
move (0+$newX) (0+$newY) (0+$i*0.15);
};
如此產生出來的向日葵花核(core)如下圖。只要改變$i角度,就可以改變核心的密集程度。
▲$i為27.8度。圖片來源:Chi-Feng。
▲$i為132度。圖片來源:Chi-Feng。
▲不同角度組合實驗。圖片來源:Chi-Feng。
看到這裡,讀者是不是能夠再仔細想想,自然界還有哪些東西是類似向日葵花一樣,暗藏上帝的傑作呢?而《少年 Pi》在特效的製作正是大量利用了Procedural Modeling 來產生令人驚豔的奇幻效果,所以說或許某些程面上,李安也是受到自然或是生物所啟發吧!
這也是在電影結束之後,我想對片尾字幕中列出,負責寫 procedural modeling 的程式人員致敬的原因。有了這些人與技術,在電影特效製作上不僅節省巨量的寶貴時間,還能夠無限制的馳騁導演的想像力。
▲Procedural Modeling 讓許多奇幻的特效有機會呈現在大螢幕上。圖片來源:apnatimepass.com。
關於作者: Chi-Feng
Chi-Feng 為旅居美國的遊戲設計師,應用科學與Fine Art 雙碩士,曾在美商藝電(Electronic Arts Inc.)任TA一職,也曾任Art institute 助理教授,現職為Western Piedmont 大學的動畫與遊戲設計講師。
關於有物報告網站
有物報告取名自言之有物、互通有無。我們針對中文世界的科技業人士,致力於打造一個鼓勵更多言之有物的內容的平台。我們已經寫過許多科技業人士有興趣的議題,並且持續的擴大作者陣容。其中一些題目包括:科技、設計、領袖、國際化、創業、法律、談判、職場生活、公司管理、人才。
沒有留言:
張貼留言