胡 冰
北京影潤文化傳播有限公司,北京 102600
攝影機作為影像創(chuàng)作的基本工具,決定了影視內(nèi)容呈現(xiàn)的視角與方式。隨著時代的進步,無論是藝術(shù)創(chuàng)作者還是觀眾,都對畫面的呈現(xiàn)方式有著更高的要求與期待。以往那些難以通過實景拍攝獲得的鏡頭效果,在數(shù)字技術(shù)的加持下,正在被逐一攻克。
圖1 The Third Floor在 《復仇者聯(lián)盟》中應用Tech Vis虛擬攝影機
當觀眾身處影院跟隨疾馳的車輛穿過槍林彈雨,或是與各種科幻角色一起遨游太空,這些緊張刺激的畫面視角,都離不開虛擬攝影機的協(xié)助。所謂虛擬攝影機,是指在三維或視效軟件中虛構(gòu)的攝影機對象,它們可以在三維空間內(nèi)任意移動而不受物理上的限制,從而實現(xiàn)對數(shù)字場景的鏡頭化表達。不僅是在影視制作的后期階段,隨著Tech Vis等視效預覽技術(shù)的廣泛應用,虛擬攝影機還能為實景拍攝提供參考依據(jù),或作為Motion Control機械臂的數(shù)據(jù)來源。因此,能夠便捷高效地應用虛擬攝影機工具,對現(xiàn)今的影視創(chuàng)作與拍攝都有著重要的意義。
盡管當今的三維與合成類軟件都內(nèi)置有攝像機(Camera)視角以及時間線動畫功能,然而在使用它們創(chuàng)建攝影機動畫時都需要較為繁瑣的操作步驟。更為重要的是,普通的三維動畫師往往并不具備十分專業(yè)的鏡頭語言表達能力,使得他們難以創(chuàng)建流暢、聚焦且引人入勝的鏡頭運動效果。因此,對現(xiàn)有制作軟件的功能進行擴展,使其能夠?qū)崿F(xiàn)更加快捷、靈活、專業(yè)的虛擬鏡頭創(chuàng)建,就變得非常有價值。
針對上述需求,市場上已經(jīng)存在部分面向主流DCC(Digital Content Creation)軟件的虛擬攝影機插件產(chǎn)品,但在靈活性方面往往無法滿足工作室用戶的特定需求,且在采購成本上對于擁有大量工作站的工作室并不友好。因此,在實際項目中,大多數(shù)視效與動畫工作室都會采取自研的方式進行開發(fā),并將相關(guān)任務委派給Pipeline TD,即管線技術(shù)指導進行完成。Pipeline TD在接到開發(fā)任務后,會遵循以下三個步驟展開工作:插件需求設(shè)計、宿主軟件擴展性調(diào)研,以及最終為實現(xiàn)插件功能編寫代碼。
對于這款虛擬攝影機插件,其應具備兩類基本功能。首先,通過包含一些經(jīng)典、常用的攝影機運動方式預設(shè),幫助用戶便捷高效地創(chuàng)建拍攝鏡頭;另一方面,允許用戶通過將三維空間內(nèi)可自定義的平滑曲線作為攝影機的運動軌道,實現(xiàn)類似 “飛貓”的高空繩索攝影機視角,從而創(chuàng)建靈活度更高、視覺效果更加震撼的鏡頭語言。下文中,將以 “Movie-Cam”命名并指代此虛擬攝影機插件。
2.2.1 宿主軟件選擇
相對于傳統(tǒng)影視制作中剪輯、調(diào)色等相對孤立的制作流程,視效與動畫行業(yè)的內(nèi)容生產(chǎn)則包含諸多環(huán)環(huán)相扣的緊密流程,即所謂管線 (pipeline)的概念。因此,與之對應的,專業(yè)DCC軟件在其架構(gòu)設(shè)計上就是面向制作管線的,通常都會提供非常全面、豐富的API開發(fā)接口,以滿足行業(yè)用戶對于自定義工作流程與生產(chǎn)效率方面的嚴苛要求。
對于像Maya、3ds Max、Houdini這類商業(yè)軟件,無論是其API接口還是代碼調(diào)試,相關(guān)支持都已十分成熟。近年來,隨著開源生態(tài)的發(fā)展壯大,越來越多的內(nèi)容創(chuàng)作者將目光投向Blender。作為一款免費開源的DCC軟件,Blender同時具備建模、動畫、視效合成等功能。根據(jù)Blender基金會官方發(fā)布的數(shù)據(jù),在2020年期間,其軟件官網(wǎng)下載量超過1400萬次。選擇將Blender作為虛擬攝影機插件的宿主平臺,可顯著降低工作室的軟件采購成本,但在此之前,需要對其開發(fā)擴展支持做深入研究。
2.2.2 Blender Python API模塊構(gòu)成
在Blender軟件的官方文檔中有這樣的描述:“能夠使用Blender標準UI實現(xiàn)的功能,都能夠通過對Blender API的調(diào)用來實現(xiàn)。”為此,Blender內(nèi)置了豐富的開發(fā)接口。其中,“bpy”作為Blender Python API的主模塊,包含了對Blender主要功能的調(diào)用接口。根據(jù)用途的不同,它們被劃分為9類功能模塊。
(1)上下文模塊 (bpy.context):提供了對上下文狀態(tài)及屬性的訪問。它將根據(jù)Blender軟件當前所處的操作模式提供不同的成員選項。需要注意的是以上下文方式訪問的值僅可只讀。
(2)數(shù)據(jù)訪問模塊 (bpy.data):提供了對Blender項目工程中全部數(shù)據(jù)的可讀寫訪問接口。
(3)消息總線模塊 (bpy.msgbus):當使用數(shù)據(jù)API修改Blender項目中數(shù)據(jù)塊 (datablocks)的屬性時,消息總線系統(tǒng)可用于接收通知提醒。
(4)操作符模塊 (bpy.ops):提供基于Python訪問的可調(diào)用操作符 (Operators),它們由C、Python或宏語言編寫,并以bpy.ops作為訪問路徑。
(5)類型模塊 (bpy.types):以類 (Class)的形式提供了對Blender內(nèi)置數(shù)據(jù)結(jié)構(gòu)的抽象。
(6)實用工具模塊 (bpy.utils):提供了諸如功能類注冊、資源路徑查找等非Blender項目數(shù)據(jù)相關(guān)的實用工具函數(shù)。
(7)路徑工具模塊 (bpy.path):類似于Python標準庫中的os.path模塊,包含了用于處理與Blender路徑解析相關(guān)的實用工具函數(shù)。
(8)應用程序數(shù)據(jù)模塊 (bpy.app):用于獲取Blender應用程序及其內(nèi)部組件的相關(guān)運行配置信息。
(9)屬性定義模塊 (bpy.props):用于通過自定義屬性對Blender內(nèi)部數(shù)據(jù)進行擴展。
從上述模塊組件的描述中可以看出,Blender插件的開發(fā)采用面向?qū)ο蟮姆绞健lender Python API通過預置類提供對軟件功能的整合與擴展。用戶通過創(chuàng)建子類來繼承父類中預先定義的屬性和方法,它們實現(xiàn)了與Blender程序間的交互接口。在上述模塊組件的基礎(chǔ)上,通過對其各自函數(shù)接口的深入調(diào)研后發(fā)現(xiàn),Blender對于虛擬攝影機插件所涉及的對象創(chuàng)建、屬性變更、時間線與關(guān)鍵幀設(shè)置等操作都提供有相應的API調(diào)用接口,可以滿足需求設(shè)計中各項功能的實現(xiàn)。
2.2.3 Blender內(nèi)置開發(fā)支持
在掌握了Blender開發(fā)接口的能力后,還需要對其代碼調(diào)試的支持情況進行評估。任何程序的開發(fā)都不是一蹴而就,在編寫代碼的同時,還伴隨著對程序功能、執(zhí)行流程的持續(xù)測試與驗證。Blender軟件默認提供了一個名為 “Scripting”的腳本調(diào)試工作區(qū),其中分別包含有一個交互式命令行、一個文本編輯器以及一個操作執(zhí)行信息窗口。
圖2 Blender腳本調(diào)試工作區(qū)
當Blender應用啟動時,其內(nèi)嵌的Python解釋器也會同步運行。用戶可通過交互式命令行執(zhí)行單步腳本指令,并借助其代碼自動補全功能,更便捷地檢索對象的屬性、方法等關(guān)鍵字信息。由于Blender API的結(jié)構(gòu)龐大復雜,且在不斷擴充,部分接口功能并未在官方文檔中詳細闡述。因此,在插件的實際開發(fā)過程中,很多函數(shù)及屬性信息,都是借助交互式命令行的關(guān)鍵字提示功能,結(jié)合單詞語義推測獲取的。
相較于交互式命令行,Blender內(nèi)置的文本編輯器則允許批量調(diào)試、運行多行代碼。開發(fā)者可通過工作區(qū)左下角的信息窗口查看單行或多行代碼的執(zhí)行情況。此外,在Blender軟件的用戶偏好設(shè)置中,提供了 “開發(fā)者附加內(nèi)容”(Developer Extras)與“Python工具提示”(Python Tooltips)選項。開啟后,當鼠標指針懸停在軟件界面任意控件的上方時,將會顯示該UI控件所對應編程接口的調(diào)用路徑,用戶通過上下文菜單還可在文本編輯器中直接查看并修改對應的Blender源代碼。
綜上所述,作為一款開源DCC軟件,Blender已經(jīng)具備了較為完善的開發(fā)擴展支持能力,在滿足虛擬攝影機插件開發(fā)需求的同時,也能為開發(fā)者帶來良好的調(diào)試體驗。
2.3.1 Blender插件基本結(jié)構(gòu)
一個標準的Blender插件通常由四部分代碼段所構(gòu)成。首先是插件的元數(shù)據(jù)部分,由一個名為bl_info的字典變量構(gòu)成,其中包含有當前插件的名稱、開發(fā)者、版本、界面位置等基礎(chǔ)信息,用戶在安裝插件時可從中獲取有關(guān)此插件的基本信息。
第二部分則包含了插件各項功能的實現(xiàn)代碼,通常由操作子類 (Operator Subclass)與函數(shù)構(gòu)成,例如對場景中對象屬性的變更或是創(chuàng)建時間線動畫等。第三部分是用戶交互界面代碼,開發(fā)者在這部分代碼中對插件的按鈕、滑塊、復選框等操作控件進行布局,同時將之前已創(chuàng)建的功能子類或函數(shù)綁定至相關(guān)的UI控件之上。
最后一部分則是插件的功能注冊模塊,包含register與unregister兩個預置函數(shù),用于對插件中自定義屬性、操作子類以及鍵盤布局等項目在運行環(huán)境中的注冊與注銷。當用戶在Blender軟件中激活或禁用指定插件時,將會分別調(diào)用它們。
2.3.2 搭建外部開發(fā)環(huán)境
盡管Blender軟件內(nèi)置了便于腳本調(diào)試的交互式界面,但當進行插件這類結(jié)構(gòu)化代碼的編寫時,仍然需要搭建一套專注可靠的開發(fā)環(huán)境。Movie-Cam插件選擇使用Visual Studio Code作為代碼編輯器,并搭配微軟官方的Python擴展插件。在配置好Python解釋器后,為了獲得針對Blender API模塊的代碼提示等功能,還需要安裝名為 “fakebpy-module”的Python軟件包。具體安裝指令為:
CMD∶>pip install fake-bpy-module-latest。
當Blender插件的外部開發(fā)環(huán)境搭建完成后,應詳細記錄所涉及到的各軟件版本信息,以便在后期代碼調(diào)試或版本迭代過程中保持一致。以下為Movie-Cam插件開發(fā)時的環(huán)境版本信息:
Windows 10專業(yè)版21 H2(19044.1889);
Blender v3.2.2;
Python v3.10.6 64bit;
Visual Studio Code v1.70.1;
fake-bpy-module-latest(20220815)。
2.3.3 虛擬攝影機插件功能實現(xiàn)
以下將分別闡述Movie-Cam插件主要功能模塊所涉及的技術(shù)要點與代碼實現(xiàn)。
圖3 Movie-Cam插件功能模塊圖
(1)導入跟蹤攝影機
為了能夠更加精準地識別和操控虛擬攝影機對象,將其與Blender軟件中的默認攝像機進行區(qū)分,在編寫代碼前,需要先使用Blender應用為Movie-Cam插件創(chuàng)建一套單獨的外部資產(chǎn)。
此外部資產(chǎn)由三類對象組成,首先是一個標準的攝像機對象,用于實現(xiàn)基本拍攝參數(shù)的設(shè)置;其次,是一個攝影機造型的網(wǎng)格模型,便于用戶更好地識別和選定虛擬攝影機;最后則是一個球狀空物體,作為虛擬攝影機的目標跟蹤對象。通過將攝影機網(wǎng)格模型與攝像機對象設(shè)定為父子關(guān)系,以實現(xiàn)兩者間的綁定。同時,利用物體的約束 (Constraint)屬性將虛擬攝影機的鏡頭朝向始終跟隨至球狀空物體,以便用戶只需操作球狀空物體,即可控制虛擬攝影機的拍攝視角。對于上述資產(chǎn)對象,都為其設(shè)置了專屬的命名空間,從而為后續(xù)的代碼編寫提供便利。
圖4 Movie-Cam插件外部資產(chǎn)模型
接下來便進入到功能代碼的開發(fā)。由于Blender Python API提供了面向?qū)ο蟮墓δ芙壎?因此在大多數(shù)情況下,插件的功能模塊都是透過子類繼承的方式予以實現(xiàn)。首先通過繼承
(2)創(chuàng)建攝影機動畫預置
此功能模塊提供了不同類型的攝影機動畫預置方案,當用戶導入虛擬攝影機后,便可從中選擇所需的運動效果快速創(chuàng)建專業(yè)的拍攝鏡頭。
通過
此處以滑動變焦 (Dolly zoom)動畫預置為例介紹其功能實現(xiàn)。Dolly zoom也常被稱作 “希區(qū)柯克變焦”,它通過鏡頭焦距與攝影機位間的反向變化,使得拍攝畫面產(chǎn)生一種連續(xù)的透視變形,來營造迷離、眩暈的鏡頭質(zhì)感。
首先,需根據(jù)用戶所設(shè)定的動畫持續(xù)幀數(shù)
當計算得出攝影機的目標空間向量坐標后,還需要獲取隨攝影機移動過程中鏡頭焦距的持續(xù)變化值。精確的鏡頭焦距改變量可通過攝影機與被攝物體間距離、被攝物體 (前景)在實際空間與像場中大小等參數(shù)計算得出。為了簡化代碼實現(xiàn)的復雜度,在Movie-Cam插件中直接將鏡頭焦距的改變值應用到攝影機動畫的出點關(guān)鍵幀。從實際效果來看,在常用鏡頭焦段下,可以獲得比較滿意的透視變形效果。式2為簡化后的Dolly zoom鏡頭焦距計算公式。
在上述功能的代碼實現(xiàn)中,使用了Blender提供的獨立數(shù)學工具模塊mathutils來對攝影機、空物體等對象的空間向量進行定義與計算。
對于攝影機動畫關(guān)鍵幀的創(chuàng)建,Blender提供了keyframe_insert方法來為當前對象在時間線中插入關(guān)鍵幀。需要注意的是,由于空間坐標位置與攝影機鏡頭焦距分別歸于不同的對象屬性類型 (物體對象與攝像機對象),故需要分別為這兩類數(shù)據(jù)屬性設(shè)定關(guān)鍵幀。
至此,滑動變焦這一攝影機動畫預置便創(chuàng)建完成。開發(fā)者還可根據(jù)需要創(chuàng)建更多的攝影機預置動畫效果,并添加至
(3)繩索攝影機動畫
相較于之前的攝影機動畫預置,繩索攝影機模塊提供了更為靈活的拍攝視角設(shè)定。其實現(xiàn)原理主要基于Blender的鉗制 (Clamp To)約束功能。通過將跟蹤攝影機鉗制約束到一條路徑曲線 (NURBS Path)上,便可將攝影機的移動軌跡與之綁定。用戶可根據(jù)需要在三維空間中自由設(shè)定路徑曲線的走向,從而創(chuàng)建比現(xiàn)實中高空繩索攝影機更具視覺沖擊力的鏡頭效果。
圖5 繩索攝影機應用場景
此功能模塊在編寫時有兩處細節(jié)需要注意:首先,應確保攝影機對路徑曲線的鉗制約束優(yōu)先于對球狀空物體的標準跟隨 (Track To)約束,否則可能導致攝影機對球狀空物體的跟蹤異常。其次,在創(chuàng)建標準跟隨約束后,還需要在代碼中明確指定跟隨軸(Track Axis)與向上 (Up)局部軸的屬性參數(shù)以確保攝影機鏡頭視角對跟蹤空物體的正確朝向。
與攝影機動畫預置模塊類似,通過分別創(chuàng)建的三個操作子類,結(jié)合動畫持續(xù)幀數(shù)自定義場景屬性,即可實現(xiàn)對時間線入點、出點以及動畫播放的控制。
(4)動畫曲線插值模式切換
當攝影機運動動畫創(chuàng)建完成后,Blender會根據(jù)所設(shè)定的關(guān)鍵幀自動創(chuàng)建一條動畫曲線,稱作 “FCurve”。F-Curve基于關(guān)鍵幀之間的插值生成,它能夠幫助用戶更加便捷、平滑地控制動畫對象的運動趨勢。
默認情況下,F-Curve采用類似貝塞爾曲線(Bezier)的軌跡設(shè)置動畫插值,即運動物體在整個動畫行程中是逐漸加速或減速的。然而對于某些應用場景,使用者更希望攝影機始終保持勻速運動,這時便需要將F-Curve的插值方式從默認的貝塞爾曲線更改為線性 (Linear)模式,Movie-Cam插件通過一個開關(guān)選項允許用戶在這兩種模式間任意切換。
首先,在代碼的注冊段新建一個名為
對于已創(chuàng)建的攝影機動畫,Blender會為每一個運動屬性值設(shè)置對應的F-Curve通道,并將插值模式保存于動畫曲線所覆蓋的每個關(guān)鍵幀中。因此,
圖6 Blender曲線編輯器
當用戶通過插件切換攝影機動畫插值模式時,可在Blender的曲線編輯器 (Graph Editor)中直接觀察到F-Curve的曲率變化。
(5)構(gòu)建UI操作面板
在完成了Movie-Cam插件主要功能部分的編寫后,便是對用戶交互界面的創(chuàng)建。Blender提供了
圖7 Movie-Cam插件操作面板
此后,使用類中的draw方法來為UI面板繪制控件并配置布局。開發(fā)者即可以將先前創(chuàng)建的操作子類以按鈕的形式添加至操作面板中,也可以直接使用Blender中的預置屬性或用戶自定義屬性作為UI面板中的字段控件。當使用屬性字段時,面板類會自動根據(jù)屬性的數(shù)據(jù)類型匹配相應的UI控件。例如此前所創(chuàng)建的枚舉型、整型以及布爾型自定義場景屬性,分別會以下拉列表、數(shù)值滑塊以及復選框的形式在UI面板中對應呈現(xiàn)。
由于Blender在繪制UI面板時,采用即時刷新機制。因此,在面板類中,還可以應用條件判斷及數(shù)值綁定等手段,實現(xiàn)更為復雜的面板布局顯示控制。
(6)鏡頭焦距快捷菜單
在現(xiàn)實拍攝中,攝影師會借助不同焦段的鏡頭實現(xiàn)不同的景別視角。同樣,Movie-Cam插件參照ARRI Master Prime定焦鏡頭組中的幾個常用焦段,創(chuàng)建了四個操作子類,用于將跟蹤攝影機的鏡頭焦距分別設(shè)定至27mm、40mm、75mm以及100mm。
Blender提供了一種稱作輪盤菜單 (Pie Menus)的交互界面,允許用戶通過快捷鍵在3D視口中將其呼出,并在幾個預設(shè)選項間快速切換。類似于視口操作面板,首先通過繼承
圖8 鏡頭焦距快捷菜單
接下來,還需要為這個輪盤菜單綁定快捷鍵。Blender對其插件采用獨立的鍵盤映射,以避免與主程序內(nèi)置的鍵盤映射產(chǎn)生沖突。因此需要為Movie-Cam插件創(chuàng)建一個專屬的鍵盤映射,指定其作用域為3D視口,即僅在3D視口處于激活狀態(tài)時響應用戶的快捷鍵指令。此處,選擇將Shift+F作為新的快捷鍵組合添加到鍵盤映射中,并設(shè)定其執(zhí)行指令為呼出鏡頭焦距輪盤菜單。最后,將上述配置對象追加至插件的鍵盤映射列表 [addon_keymaps]中即可。應當注意的是,在插件末尾的注銷函數(shù)段,同樣需要將之前配置的快捷鍵映射清除以釋放資源。
最終編寫完成的代碼及虛擬攝影機資產(chǎn)文件以zip方式打包后,即可作為插件供Blender安裝使用。Movie-Cam插件從其開發(fā)工具到宿主平臺,均基于開源軟件打造和實現(xiàn)。為供廣大從業(yè)者使用和參考,現(xiàn)已將此插件免費開源發(fā)布。代碼網(wǎng)址:https://github.com/filmlight/movie-cam-addon。
當下,以虛擬攝制技術(shù)為代表的新技術(shù)的興起,促使傳統(tǒng)影視與CG動畫、數(shù)字游戲等領(lǐng)域在制作手段上有著越來越多的共通之處,Movie-Cam虛擬攝影機插件能夠同時為上述領(lǐng)域的內(nèi)容生產(chǎn)帶來便利。后續(xù),通過對該插件功能的進一步擴展,還可將其應用于Motion Control、教學演示等諸多場景。