劉德新
中影動畫產(chǎn)業(yè)有限公司,北京 101400
三維軟件中的幾何體 (Geometry)是依據(jù)三維空間中不同位置的點 (Vertex)組成的。三個點形成一個可見面,相對平滑的表面需要的點少,結(jié)構(gòu)復(fù)雜的表面需要的點多。這些表面最終通過著色系統(tǒng)生成可視化的圖形圖像。在現(xiàn)實生活中通常稱之為 “三維模型”。動畫制作中的資產(chǎn)概念是指包含了模型、材質(zhì)和綁定三種數(shù)據(jù)的綜合型文件,所謂綁定 (Rig),就是在三維軟件中通過對三維模型添加變形器 (Deform)、骨骼 (Skeleton)、動態(tài)模擬(Dynamic)(其中的一部分功能),從而影響模型上局部的點或全部的點,使其可以按照綁定師的意圖變成新的形態(tài),再通過控制器 (Controller)鏈接到以上幾種不同的影響方式上,最終達到通過控制器可以自由地控制模型形態(tài)來完成各種動畫動作的一系列操作。只有在綁定工作完成后才被視為 “可用的資產(chǎn)”,才會被批準上傳給動畫部門使用。Maya的綁定文件是一種對技術(shù)和規(guī)格要求都很嚴謹?shù)奈募问?有明確的技術(shù)標準來處理以上幾種類型組件間的邏輯關(guān)系,并且提供保護其綁定組件不被隨意篡改的功能。綁定的內(nèi)容根據(jù)制作難度又可細分為場景、道具、角色三種情況,是整個動畫工業(yè)中規(guī)范化和自動化需求最高的工作。以道具綁定為例,由于每個道具模型都需要使用同樣的綁定規(guī)格,為了減少重復(fù)勞動最大幅度的簡化道具的綁定工作,是本次筆者著手編寫綁定工具箱的初衷。(下文中提到的綁定工作均默認在Maya中進行)
在一個模型文件中會包含幾何體 (Geometry)和用于分類和管理這些幾何體的組 (Group)。綁定文件會在此基礎(chǔ)上將添加其他用途的內(nèi)容,為了方便文件管理和規(guī)范制作標準,這些 “組件”通常在命名時會使用前綴或者后綴來區(qū)分不同物體的類型,并且會被放置在某種固定的層級結(jié)構(gòu) (Hierarchy)中,這就是所謂的 “綁定的規(guī)格”。
如果遇上結(jié)構(gòu)復(fù)雜或者運動復(fù)雜的模型,往往需要添加更多的控制功能。比如汽車的綁定通常會為車身和四輪添加單獨的控制器以實現(xiàn)在顛簸時每個部分都可以進行單獨的表演。為方向盤添加控制器時需要注意控制器和模型的傾斜角度要保持一致。車門、座椅、擋位、后視鏡每個可以動的部分都可能會在考慮的范圍內(nèi)。從更豐富綁定的功能上來說,還可以在車輛向前或向后運動時添加車輪根據(jù)移動的距離自行轉(zhuǎn)動的功能,甚至是車輛發(fā)生碰撞時車身出現(xiàn)的凹損變形等。
每添加一個控制效果幾乎都需要添加相應(yīng)的控制器,然后與模型匹配中心點和軸向,最后鏈接屬性到模型??刂破饕话闶褂们€來制作,由于在Maya中提供的曲線類型非常單調(diào),為了動畫師在使用綁定文件時更直觀,綁定師經(jīng)常需要花費時間根據(jù)模型手動制作形狀更加貼切的控制器 (方形、立方型、圓形、球形、箭頭指向形等),以及設(shè)置控制器的顏色,也經(jīng)常會發(fā)生替換更合適的曲線形狀的情況。由于幾乎每個綁定文件都會添加很多控制器,因此在控制器方面的需求也是需要進行程序化的重點內(nèi)容。
圖1 汽車模型和控制系統(tǒng)
綁定師在使用Maya時會根據(jù)自己的工作需求經(jīng)常使用到一些在不同模塊不同菜單里的命令,按照類型來劃分,凍結(jié) (Freeze)、刪除歷史 (Delete History)、中心點 (Center Pivot)是第一類。常用變形器比如融合變形 (Blend Shape)、晶格 (Lattice)、簇 (Cluster)、曲線變形 (Wire)是第二類。骨骼相關(guān)的命令是第三類。如果能把這些命令集成在一個工具面板里,使用起來會方便得多。最后還有一種特殊類型的命令,以拷貝蒙皮權(quán)重命令(Copy Skin Weights)為例,在兩個蒙皮物體間拷貝權(quán)重效果通常都是正常的,但是將一個物體作為基礎(chǔ)向多個物體同時拷貝權(quán)重時則無法正常工作,這時需要把此類命令用Python改寫成循環(huán)語句才能夠達到預(yù)期的結(jié)果。
Maya中提供的鏈接方式主要有約束 (Constrain)、屬性鏈接 (Attribute Connection)、驅(qū)動關(guān)鍵幀 (Set Driven Key)三種。約束命令在Maya中操作簡單,只要選擇相應(yīng)的物體點擊命令就可以了。但是屬性鏈接的操作會稍顯復(fù)雜,需要使用屬性鏈接編輯器 (Connection Editor)或者節(jié)點編輯器(Node Editor)來完成操作。對于物體最外層的移動節(jié)點 (Transform Node)的鏈接操作來說還是有值得用Python語句優(yōu)化的必要,這樣可以免去打開屬性鏈接編輯器或節(jié)點編輯器的必要。
綁定文件在功能性上制作完成后,為了保護其不被篡改,可以對文件中的某些指定內(nèi)容予以鎖定或者隱藏。
Maya的內(nèi)置腳本類型為MEL,此外它也支持C、C++、Python等多種語言類型。
制作類程序的開發(fā)主要是依托Maya已有的命令和綁定的制作規(guī)范,是功能相對單純的程序。這種形式的程序?qū)⑺械墓δ?(Function)和界面(UI)編寫在一個腳本內(nèi),最后通過界面中的按鍵(Button)調(diào)取各自需要的功能 (Function)以達成既定目標。由于幾乎不會涉及到其他部門和影響整體流水線,編寫和調(diào)整十分靈活,缺點是承載的內(nèi)容有限。
另一種是為了配合生產(chǎn)線,并且會涉及到各個部門間協(xié)同工作的結(jié)構(gòu)復(fù)雜的程序。這種程序可能是Maya內(nèi)部的,也可能是與其他軟件相鏈接的。形式上通常會把每個功能寫成單獨的程序存放在固定的路徑中,然后編寫一個更大的框架程序來調(diào)用這些子程序。界面程序的按鍵命令會調(diào)用路徑下單獨存放的功能程序。在強調(diào)流程的前提下,這種方式更便于程序的管理和維護。
與其說在Maya中使用Python,不如說是在Python編譯器中使用Maya的命令。在使用Maya的腳本編輯器 (Script Editor)中的Python編輯器開始寫作前,需要將Maya的命令導(dǎo)入Python編輯器,以幫助Python理解Maya命令。
通過整理流程規(guī)范和收集工作中的需求我們已經(jīng)明確了此次需要程序化的工作內(nèi)容,接著我們來逐個分析,找到適用于編寫它們的Python命令和語法。
本文 “1.1”創(chuàng)建綁定層級 (Hierarchy)的工作大致可以歸納為以下內(nèi)容:添加一個立方體形狀的曲線 (Curve)作為主控制器,調(diào)整曲線匹配模型的范圍。添加一些組,修改這些組和曲線的名字。把模型、組、曲線 (此時已變成控制器)按照綁定規(guī)范放置到適當?shù)膶蛹壩恢?。最后再添加一些基本功?比如杯子重心的切換 (從杯底到杯子間),為防止模型被誤碰還需要添加控制顯示模式切換的屬性。
在人工操作的情況下這是一種線性不重復(fù)的工作流。每個步驟只操作一次,且步驟非常多。當換作用Python程序的方式來進行描述時是這樣的:工作類型一:各種和創(chuàng)建相關(guān)的命令,負責創(chuàng)建整個綁定過程中需要的所有必要的組件。如用于基本結(jié)構(gòu)的空組 (Null)、標準比例主控制器線條 (空間比例1∶1∶1的CV曲線)、定位器 (Locator),以及各種運算節(jié)點 (Node)。也可以將為物體添加自定義屬性 (Add Attribute)看作是一種子級的創(chuàng)建工作。工作類型二:屬性的獲取 (Get Attribute)和賦予 (Set Attribute),負責獲取不同物體中必要屬性的數(shù)據(jù)并將其保存到變量中,在其后的工作中根據(jù)需要將這些變量賦給其他物體的屬性。如通過提取模型體積范圍的數(shù)據(jù)賦予到標準控制器,使控制曲線得以匹配任何模型的體積范圍。工作類型三:負責屬性連接 (Connect Attribute),通過控制器將不同物體或者計算節(jié)點的可用屬性連接起來,最終達到預(yù)期的可控效果。最后一種工作類型是調(diào)整層級結(jié)構(gòu)的命令 (Parent),用于將各部件按照既定規(guī)格放置到標準的綁定架構(gòu)中。這樣便實現(xiàn)了所有的工作目標。經(jīng)過考慮還特意增加了Deform Reor和JointReor兩個按鈕,可以把選中的內(nèi)容快速放置到變形器組或者骨骼組的層級結(jié)構(gòu)中。
圖2 右圖的綁定文件在層級結(jié)構(gòu) (Hierarchy)上發(fā)生的變化
圖3 鋼琴按鍵批量創(chuàng)建的控制器
本文 “1.2”提到的控制器一般使用曲線圓環(huán)(NURBSCircle)來制作。鋼琴可以作為一個既常見又極端的綁定案例,由于無法預(yù)知在動畫制作階段具體會按到哪些琴鍵,為所有的琴鍵都添加控制器是權(quán)宜之計,是重復(fù)勞動的典型案例。此時工作需求進一步提升了,從最開始的為單一物體創(chuàng)建控制器變成為很多物體批量創(chuàng)建控制器 (Controller)。對應(yīng)的方法是使用Python語言的ls命令生產(chǎn)列表來判斷當前選擇了的物體,然后通過for循環(huán)語句為列表中的物體依次創(chuàng)建曲線圓環(huán),匹配中心點和軸向,修改圓環(huán)名稱,添加約束到物體。修改控制器顏色 (彩色按鈕)或替換控制器曲線形態(tài) (Replace)的情況是一種對已有對象的 “修改”行為。最初的做法只考慮了對當前物體 (Select)進行一對一的修改。為了方便工作也都將程序改寫成批量處理的形式。
曲線 (Curve)是通過空間中不同位置的點來形成的,控制器曲線是通過程序自定義了曲線上每個點的位置來實現(xiàn)的。曲線可以單獨當作控制器來使用,也可以通過Replace按鈕替換到其他的控制器形態(tài)。
圖4 多種形態(tài)的控制器
本文 “1.3”中的Maya常用命令整合僅僅是把需要的命令逐個羅列在程序里即可。為了區(qū)分命令種類,特意把它們分成了上下兩個部分。本文“1.4”需要實現(xiàn)的是用第一個選擇的物體對第二個選擇的物體進行移動旋轉(zhuǎn)縮放三種屬性的鏈接(Connect)或者約束 (Constraint),同樣使用列表命令來判斷選擇的物體,然后對列表中的兩個物體需要的屬性進行鏈接。此外還使用for循環(huán)語句添加了前文提到的批量拷貝權(quán)重 (Copy Weight)的功能。
圖5 在Outliner中隱藏掉不想被意外改動的內(nèi)容
本文 “1.5”最終化面板提供兩種鎖定方式,一種是鎖定物體的基礎(chǔ)屬性,一種是最終化鎖定。兩種功能針對的內(nèi)容是不同的,同樣也提供對應(yīng)的解鎖功能。需要說明的是為已完成的綁定文件進行最終化的需求并不常見,實現(xiàn)這一功能方式是對綁定架構(gòu)中已有的且固定的組件名稱進行拾取,并將其信息在大綱視圖 (Outliner)內(nèi)進行隱藏操作。使得非綁定人員在打開文件后看不到控制器以外的綁定信息,從而達到保護綁定文件的作用。
通過以上的介紹可以發(fā)現(xiàn),大部分的程序是以基本的命令和簡單的邏輯語句來完成編寫的。要注意的是Python語句的特點是每行只能執(zhí)行一個命令。在Maya中執(zhí)行Python語句只要是格式正確都可以被執(zhí)行。但是為了能夠把這功能性命令通過可視化的界面來執(zhí)行,需要把每個完整的命令序列封套進def函數(shù)并指認到特定的按鈕命令中才能被調(diào)用。Maya的Python命令中提供非常豐富的界面編輯類型,通過在Maya幫助文件的命令檢索中查詢Layout一詞,可以得到非常多關(guān)于界面布局的命令,筆者使用的第一個UI就是基于Maya提供的幫助文件。但是隨著功能的增多,后續(xù)的版本改為了混合型的Layout布局。
工具的開發(fā)是一個循序漸進的過程,也許最開始只是單純?yōu)榱藴p少某項重復(fù)勞動。作為編程的起點,很多Maya用戶會通過復(fù)制腳本編輯器中已經(jīng)執(zhí)行好的MEL命令,就可以有效地減少重復(fù)工作了。如果能有目的地對這些程序進行篩選并去掉不需要的部分,工作效率會提高地更多。在Maya中使用Python命令有兩個基本前提:一是需要專門學(xué)習(xí)Python的編譯方式,二是學(xué)習(xí)Maya幫助文件中的Python命令和借鑒其提供的腳本范例。從單行的命令開始逐步掌握循環(huán)語句 (for語句)、條件語句 (if語句)、函數(shù) (def)等編寫形式。建議把界面看作一個獨立的部分去學(xué)習(xí)掌握。筆者在完成最初幾個小功能的代碼時完全沒有考慮會為其編寫界面程序,隨后逐漸開始樂此不疲,幾乎將以往累計下的所有需求逐個進行了程序化,并最終整合到同一個腳本中。
從圖6來看,V01版本中最初的想法只是為了完成需求1.1道具綁定的層級 (Props Puppet Create)和需求1.5綁定文件的最終化 (Props Rigging Finalize)。在V04版本中加入了1.2為物體添加控制器和調(diào)整控制器顏色的功能,由于新按鈕是接在上個版本的下面,導(dǎo)致這個版本過于浪費界面空間,布局和顏色都是默認參數(shù),不夠美觀。第V06版本在界面布局做了較大調(diào)整,選擇了新的Layout布局命令,并重新規(guī)劃了功能分區(qū)。根據(jù)工作需求分為層級創(chuàng)建 (Hierarchy)、控制器 (Controller)、屬性鏈接 (Connection)、最終化 (Finalize),可以算得上是最終版的雛形了。在V10版本中添加了控制器形態(tài)參考 (ShapeRef)用于創(chuàng)建形態(tài)各異的控制器,并將原來的控制器顏色設(shè)置按鍵 (Color)的字母顯示去掉,改為了以不同色塊形式表現(xiàn)的按鈕,使其更加直觀便于使用。在最終的版本V13里添加了常用的需求1.3的Maya常用命令集合 (Maya Command),隨著經(jīng)驗的累積,能力的提升,還添加了以前并沒有考慮過的重新命名工具 (Rename),并按照工作流程和使用習(xí)慣確認了最終的布局。
圖6 不同時期的版本演變
和所有學(xué)習(xí)Python的初學(xué)者一樣,從在Python編譯器中打出“Hello Python”開始,到在Maya中執(zhí)行第一條Python命令。從390行代碼三個功能按鍵的V01版本,到最終版976行代碼五十一個功能按鍵的V13版本?,F(xiàn)在回頭想想,最重要的感受還是工作需求是第一學(xué)習(xí)動力,經(jīng)驗都是在摸索中實踐,在實踐中摸索,慢慢積累而來的。筆者從2019年1月開始接觸各種學(xué)習(xí)資料,5月嘗試寫完了第一個功能創(chuàng)建綁定層級 (Hierarchy)的基礎(chǔ)部分后,不僅由于工作太忙,自己對Python的掌握程度也不足以支撐寫下去,綁定工具開發(fā)的事情就戛然而止了。直到10月習(xí)得界面的寫法,11月每周更新一次,12月更新了一次然后又被有限的知識卡住了。最終在2020年4月更新了6次后完成了功能上的定稿,最后在5月和8月各更新了一次界面??傮w上看花在寫腳本上的時間只有兩個多月,但收獲這一成果花費將近一年半的時間。此間,筆者翻閱了大量的Python書籍和網(wǎng)絡(luò)教程,經(jīng)常是一手查資料一手看幫助文件,逐字模仿逐句揣摩。面對各式各樣的教材,筆者發(fā)現(xiàn)基礎(chǔ)的教材不足以解決當前遇到的實際問題,高級教材又晦澀難懂,因為自身的能力和經(jīng)驗都不足無法將其轉(zhuǎn)化為實際生產(chǎn)力。最困難的一步是如何將自己豐富的工作經(jīng)驗和有限的編程知識結(jié)合起來,最終寫出可以解決具體需求的工具來。
正所謂 “不積跬步無以至千里”,如果您也像筆者一樣,發(fā)現(xiàn)工作中存在大量的工作都有待被提煉、被規(guī)范,那么就值得花些時間來學(xué)習(xí)編程語言。此工具箱早已投入到生產(chǎn)當中,在不同的項目中發(fā)揮了積極的作用,可以明顯感受到工作效率的極大提升。原本工作中需要幾個、幾十個的操作步驟,幾分鐘到幾十分鐘才能完成的工作,現(xiàn)在只需要在綁定工具箱中點擊相應(yīng)的按鈕,很多工作只需要零點幾秒就完成了,真正實踐了以科學(xué)技術(shù)為第一生產(chǎn),解放生產(chǎn)力,提高生產(chǎn)力。動畫行業(yè)的技術(shù)工作在諸多方面都對流程開發(fā)或者技術(shù)開發(fā)有著龐大的需求,希望有更多的同仁能關(guān)注中國動畫工業(yè)的發(fā)展,并能有興趣參與其中,在不同的領(lǐng)域里為業(yè)界提供優(yōu)質(zhì)的解決方案,共同促進行業(yè)的發(fā)展。?