2018年7月20日 星期五

Pre-Bake 360 如何利用360轉錄技術製作無模型場景

本文作者 Kelvin Lo

-文長-
想要讓手機能和PC擁有同樣的畫質水平,一直以來都是開發者追求的,但現實是礙於現下的軟硬體技術力,團隊必須要跨過相當大的技術門檻,對於一般開發者來說它就像是一座天秤,畫質與效能各自在天秤的兩頭,你必須有所取捨。

在以前,遊戲開發不像現在有那麼多的資源能運用,往往一個畫面要透過許多技巧或各種假畫面來欺騙玩家眼睛來達到在當時技術門檻難以達到的畫面。本文主要分享的內容是如何利用Unity 2018新的拍攝API來實現高質量畫面低Draw Call的場景技巧。

本專案採用Unity官方釋出的一個Demo叫Space Shooter,這是一個2D橫向捲軸射擊遊戲,用非常簡單太空圖片作為背景,在本文章裡,我們把背景換成了影片後,保持了原來的效能消耗,但畫面比起原來的版本要好許多。


改變前



改變後



影片展示

雖然畫面變好看了,但對於玩家而言還是太過單調,所以我們做了第二次的調整,把運鏡的感覺與攝像頭有限度的轉動導入了本次的改變,效果就好很多,而且Draw Call並沒有增長太多,結果如下:


第二次改變影片展示

之所以可以讓場景保持低消耗還能有這樣的畫面表現與互動,是因為這次採用的是360影片




用360影片作為場景


雖然這樣的呈現非常棒,但是有很多限制的,由於是影片格式,所以佔用的硬碟空間相對的就比原來的貼圖大很多,目前Untiy的Video Player尚未支援串流,因此必須把影片先放進專案中,或是透過URL模式下載,但仍然會佔用較大的專案空間。這種用360的產品互動設計也相對困難,最重要的是這種專案鏡頭只能轉動,不能位移。

雖然有上述的限制,但是好處就是可以讓手機產品做到接近PC的品質,而且再也不用擔心不同手機晶片會有無法執行的問題。這樣的作法當然也因為限制的關係只適合特定的遊戲類型。

簡單來說就是鏡頭不能移動(腳不用動)的類型:

飛機射擊遊戲遊戲
雲霄飛車遊戲
跑酷遊戲
上帝模式密室脫逃
博弈類機台

Unity 2018新的API



要把場景回拍成360可以採用Unity 2018兩個新的API:

Camera.RenderToCubemap()可以從相機的位置對環境拍攝一張Cubemap



這樣的圖可以做為Cubemap貼回Skybox。

或是用RenderTexture.ConvertToEquirect()把這張Cubemap在縫合成為一張全景圖(Panoramic images)



最後會算成一張這樣的圖,把這張圖包在一顆球上從裡面看就可以還原當時的場景。

最終結果

錄影套件:Recorder


實際上這個測試專案採用了Unity官方釋出的套件Recorder,這個套件完美的採用上述兩個API並且可以和Timeline整合在一起(必須是Unity 2018或以上版本),搭配Cinemachine的Dolly track軌道安排的路徑,能依照我規劃的路線拍出我要的鏡頭。


Unity2018以上版本就可以看到有能錄製360的選項



透過Dolly Track來安排我的鏡頭動線,依照路徑錄製場景移動

Post Processing後製特效

一般來說,在手機平台的特效都會建議能少開就少開,遮擋剔除(Occlusion Culling)或是場景LoD能多用就多用,但在這種預烘焙案例裡,反而是建議是把所有能開的特效全開,遮擋剔除和LoD能不開就不開,為的就是預烘焙的品質可以得到最好。


PPS OFF


PPS ON

由於PPS的特效有些是基於螢幕空間計算,因此要注意的是某些特效不適合用在這種流程,否則就會烘出下面這種有問題的圖


並非所有後製特效都適合烘焙360

Masking遮擋技巧

如果我們想讓飛機飛過一座橋底下,但一般來說這種預烘焙360圖層已經扁平化,沒辦法做到在物件底下的效果,這時我們可以另外烘焙一層遮罩來達成我們想要的效果。


用兩層360來製造飛機飛過橋下的效果

Unity原生支援兩種帶有Alpha頻道的影片格式,分別是Apple的ProRes 4444和Google的Webm VP8,但在本次測試我們並沒有採用這兩種格式,主要是因為製作不易之外,多一個Alpha頻道也讓空間佔用更大。

我們採用業內比較常見的Chorma Key,也就是把顏色去掉的綠幕作法。值得一提的是我們把石橋和橋上面的物件單獨設定為一個Layer,然後在相機裡面設定Clear Flags為Solid Color,綠色。Culling Mask設定只顯示石橋那一個Layer,結果就會只渲染石橋與上面的元件,其他部分都會只渲染成綠色。這樣的好處是完全不需要去切換物件的位置或是狀態,很簡單就能在不同圖層切換。

最後再包回圓球並用Shader把綠色都挖掉,就會呈現出如下圖的樣子,只要渲染在飛機之上就能呈現出經過橋下的效果,由於它也是一個影片,因此可以完美無瑕的和背景影片結合再一起。



綠幕作法

靜態圖片的360場景

介紹完用360影片製作的場景之後,我們來說說如何用靜態的360圖片來製作場景,利用圖片的好處是硬碟空間佔用比起影片小非常多。我們採用一個密室脫逃的遊戲類型來當作Demo展示,主角在一個有六個房間和一個走廊的建築結構裡行走,每個房間都帶有一個鏡頭,主角可以自由行走在這些房間,鏡頭會主動判斷切換。


Demo場景來自於ArchViz Pro No.3

你看到的畫面實際上並不存在真實的3D建築模型,而是在七個不同的360圖片之間作切換,並共用同一組碰撞結構,進而能達成這樣的效果,重點是Draw Calls還是維持非常低的20以內,很神奇對嗎?

360場景原理


這場景是如何製作的呢?首先我們還是必須要有建模流程,我們從Asset Store買了一套著名的Archvizpro interior No.3室內設計模型作為本次Demo的模型,在還沒烘焙成360之前,正常播放大約Draw Calls平均是2500-3000左右。我們在場景的每一個房間安置了Cinemachine的虛擬鏡頭(下圖紅點處),然後各自用Recorder錄製了一張全景圖。


建模流程

場景拍完後,我把所有的Mesh renderer元件都移除,這會讓場景只剩下Collider碰撞結構,每個房間的鏡頭位置都加上一個Sphere圓球,並把剛剛拍好的全景圖各自貼回去對應的房間,材質Shader指定為Skybox-Panoramic。由於碰撞結構沿用場景原本的Colliders,鏡頭的位置也都精準的放在對的位置,因此你會發現這時候的鏡頭看出去和碰撞結構的位置會完美的疊合一起。


將模型材質都清除只留下碰撞結構



修正簡化碰撞結構後,場景各自被圓球包覆眼睛看出去和碰撞結構可以完美疊合

Shader選擇與自訂

Unity內建的Standard Shader並不適合用在全景圖上,Skybox-Cubemap才適合,但Cubemap不適合用在影片格式的全景圖,因此展示時我們是採用也是內建的Skybox-Panoramic的Shader,但目前這兩個內建的Shader並沒有綠幕Key的功能,為了要一個Shader有兩個功能,我從官網下載Skybox-Panoramic Shader的原始碼,然後自行加上Chroma Key或Alpha Key的功能,通常是公司的TA技術美術來負責這個工作。


Panoramic Shader放360圖片線條才不會歪掉,為了讓一個Shader有兩個功能,稍微加工了一下Shader


有了這個Shader之後,運用和前面影片的遮罩製作方式,一樣把要留住的物件標記為獨立的Layer,然後從Camera去過濾留下要作為前景的物件拍出一張帶有Alpha的圖片或如下圖的綠底照片(依據你的Shader類型而定):



把箭頭的物件都設為一個Layer,利用鏡頭過濾掉其他的物件就不用移動物件或關閉物件來達到拍攝需求。


拍好的綠底Key圖片

靜態圖片和動態影片不同的是,你可以用帶有Alpha的圖片,甚至用其他的軟體來處理圖片,Unity設好後可以很容易就把不要的地方挖掉。

採用Alpha的圖片設定


由於人的眼睛在固定的定點時,只有一隻眼睛所看到的畫面並無深度資訊,好比場景被渲染到畫面之後就已經扁平化了,因此不管疊了多少層,人眼都無法感知深度的變化,我們可以利用這點來疊上無限層數的前景,你可以隨心所欲的設計各種不同的遮擋區域來達到幾乎跟真實3D場景一樣的前後效果。



但是要注意的是這種作法鏡頭不能移動,但可以360度的轉動

影片鏡頭只能轉不能移動




渲染前後順序

在一開始的場景你或許會覺得很奇怪,為什麼球體都那麼小?

由於為了要確保主角一定要在背景前面與前景後面,這個Demo在程式腳本做了一些判斷來動態的調整前景和背景的Render Queue,確保主角進入房間之後,該房間的背景和前景都會對應正確的數字,讓主角渲染在背景之前,前景之後。
這樣不管球體多小,他一定會在人物之前渲染。

利用Render Queue來排序前後關係

陰影處理

360原理是被一個圓球包覆,實際上沒有真的地板來投放陰影,因此許多AR或是這種360場景都沒有做陰影處理,實際上你可以放一片Mesh在腳上跟著主角,陰影會產生在這片臨時地板上,再透過Shader把陰影以外的部分去除掉,調低光源的強度讓陰影帶有一點半透明,就會產生不錯的影子效果。


陰影效果

窗戶投射的光源

為了要讓主角更加融入場景,我們希望主角走過窗戶時要有光投射到身上的效果,我們可以很簡單的把這個房間的背景圖複製一份之後,用Photoshop處理剩下光照的部分並把圖片設定作為Cookie

最重要的設定是alpha source要設定為From Gary Scale才能以圖片灰階為Alpha。

在鏡頭的位置擺設一顆Point Light之後,指定這張Cookie並只對主角有作用,就可以達到在對的位置投射窗戶的效果到主角身上,完全不需要任何模型作為基礎。是不是出乎意料的簡單?

採用Point cookie製作窗戶光影

製作鏡子反射


還原鏡子的反射在這裡我們用了第二隻鏡頭放在鏡子位置的後面,並且只設定對Player物件有反應,因此主角走過去之後會被鏡頭捕捉到,並做成一張Render Texture貼到原本鏡子該有的位置,從畫面上看來就可以造成幾可亂真的鏡子疊合假象。


鏡子反射

自動切換鏡頭

這個Demo的鏡頭切換採用Cinemachine裡的Clear shot鏡頭功能,他可以指定一個鏡頭群,並智能的判斷該切換到哪一個房間鏡頭,完全符合這個專案需求。


利用Cinemachine裡的Clear shot製作自動切換鏡頭


互動製作

從鏡子的製作你可以發現到,如果你有一些想要互動的物件,你仍然可以把他們留在場景裡不要刪除,這些物件在鏡頭觀看的時候還是會完美的和360疊合一起毫無維和,然後用一般的開發流程來幫他們加上互動要素。
360場景留下一台可以互動的拉霸機模型物件


總結

這樣的專案有幾個問題點:

  • 對於影片格式的360佔用空間要注意
  • 互動製作會因為場景扁平化之後變得比較不容易
  • 鏡頭必須動的專案類型不適合


這種專案的好處有:

  • 不管模型多複雜,效能都很好
  • 不管什麼奇怪的設備,能播影片的都能跑
  • 專案分為兩個一個用來錄製360, 一個作為產品專案會很小


其他注意事項:

  • 錄製360的Unity必須要2018以上,產品專案則不需要。
  • LoD, OC不要開
  • PPS 能開就開
  • 帶有文字的場景烘完後從內部看字會相反,這時可以從影片來源先水平翻轉一次。
  • 強烈建議4K品質效果會比較好



用攝影機拍攝的360是否也能這樣處理?
或許你有一個疑問,如果是用360鏡頭拍攝的是否也能夠做同樣的處理?答案是可行的,但它的處理方式又會有很多地方需要注意。以下是一段演講錄影,對於本次內容有問題的也可以參考這段影片。希望這些說明能給你帶來一些啟示。


沒有留言:

張貼留言

著作人