2018年9月19日 星期三

直播回顧 - 快樂的Minecraft 我的世界 ECS快速開發

作者:Kelvin Lo

片頭展示



直播影片回播

受到了上次Mike大叔的ECS教學啓發,我用一場GameJam活動的時間來製作了一個快速呈現ECS強大的簡單專案-Minecraft我的世界,當然沒辦法還原像是紅石系統這類高難度的功能,基本上就是挖礦和放石頭這兩個主要功能,重點在於如何利用ECS產生廣大的地形,以及體現ECS所提倡的要點-Performance by Default,在不考慮程式及任何優化的情況下,做出來的場景還能保有很好的效能。

Unity從2018開始導入ECS框架,紀錄這篇文章之時ECS仍然是體驗版,代表每一次的更新都會加入非常多的新功能,因此本篇文章僅算是我對當前ECS(Unity 2018.2.6, Entities 0.0.12)的體驗心得報告。

為什麼ECS的效能會超越GameObject+MonoBehaviour那麼多呢?我歸類為兩個要點,傳統方式的記憶體管理是分散式的,即物件和它身上的組件(Component)並非在同一個記憶體區段,每次存取都非常耗時。而ECS會確保所有的組件資料(Component Data)都緊密的連接再一起,這樣就能確保存取記憶體資料時以最快的速度存取。



這裡所提到的傳統組件Component和ECS的C,即Component Data雖然名字很像但卻是很不同的概念,舊的Component會乘載著不同的資料與邏輯功能,不同的Component代表著不同的功能。但在ECS裡,Component只會儲存單純的Data,不會有任何的邏輯運算,所有的邏輯運算必須拆離到S,即System裡面去實現。

也因為傳統的Component為了方便使用,整合了所有可能會用到的變數,不管你用得到或是用不到。好處就是一個Component可以解決很多事情,比如Transform,帶有Position, Rotation, Scale,透過這些參數很容易對物件處理位置或移動縮放處理。但這些你用不到的變數對於記憶體來說一點也不友善,尤其時物件非常大量時。

因此ECS把很重要一個概念就是管理只需要的Data即可,例如我的物件只需要處理渲染和移動,我當然就不需要紀錄Scale資料。





再來說說幾種方式產生Entity物件:



可以看到這張圖中Hierarchy裡只有一個方塊物件,但畫面卻有3個方塊,原因是左邊兩個是透過ECS產生的Entity物件,會獨立顯示在Entity Debugger內。雖然目前是分開顯示的,但我們最終目的是重新打造一個讓開發者接受的一個統一編輯環境。

而左邊兩個Entity物件分別採用兩種不同的方式產生,整段程式如下:



我先宣告了一個EntityManager管理器manager,然後在它底下生成了一個Archetype,這種EntityArchetype能確保存放在裡面的Component Data都緊密的相連,當你一次性產生大量的Entities並給予各種邏輯運算時,這種結構在記憶體與快取之間的移動效能直逼memcpy。

從41-49行程式就是基於Archetype結構在裡面生成一個Entity並給予座標資料與渲染資料,即指定渲染哪個Mesh和Material。最後這個方塊只帶有座標Position, 自訂的BlockTag和用來渲染的MeshInstanceRenderer三個Component Data遠遠比傳統的Game object資料少很多。這種產生方式沒有連結任何Unity編輯器上的功能,只是單純的產生Data和處理Data,可以稱為Pure ECS。

54-58行程式負責渲染最左邊的方塊,為了讓開發更直覺我希望產生Entity時引用一個Prefab,雖然Prefab是傳統Game Object,但在實例化成Entity時,Unity會自動把跟ECS無關的Component拆離,只留下Component Data產生Entity物件。這種跟Unity整合的流程,可以稱為Hybrid ECS,也是Unity在整合ECS的主要路線。

這個範例還用了一些新的功能例如新的NativeArray和定義像[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
這樣的Attributes屬性來確保函數能夠運行在想要的順序上。

如何產生世界地形


為了要讓地形能更像Minecraft的產生方式,它必須符合幾個要點:無接縫,無限大,亂數地形等等,採用Perlin noise處理這種地形是在適合不過了,Perlin noise可以有規則的亂數產生一個波形資料,作為世界的高度資料參考非常適合,我可以先產生一個足夠大的高度圖然後只用一小部分即可,如果未來要延伸地形只需要繼續生成它就會不斷延伸下去不會破掉。







具體把這個高度資料用方塊選染出來大概會長這樣



只留下高度0-6號的方塊,感覺世界形狀就出現了



從程式針對不同高度的Entity給予不同的Material資料,就可以產生我的世界,針對高度0的地表,也可以隨機產生花草或樹木。



嘗試產生了一個沒有任何優化處理,17萬個方塊的我的世界還能保持在40FPS以上,心裡有些激動。


產生物理地表


由於Unity ECS尚未支援物理系統,因此目前要實現物理要自己寫碰撞邏輯,或是沿用舊的Collider來檢測碰撞,作為一個Gamejam專案,自己寫是不太實際的而且我預期很快的Unity ECS會支援物理系統,因此我決定採用最簡單的方法,每個Entity方塊都加上一個Collider,一方面可以作為地板一方面也可以檢測挖掘和放置方塊。

這是一個全部方塊的座標同時都加放一個Collider物件的地形,除了第一幀稍微耗時之外,運行時並沒有帶來太多的消耗。



有了地形就可以放上大家熟悉的FPS Character第一人稱角色,繼續處理方塊的挖掘和放置。

製作放置方塊比挖掘方塊來得簡單,我們從鏡頭發射一個Raycast,打到任何Collider就依照當下normal的方向產生一個Collider與一個Entity物件,並依照選擇的貼圖指定給該Entity帶有的MeshInstanceRenderer內的Material即可。程式如下:



但是挖掘方塊就沒那麼容易了,主要是因為當前的Entities版本尚未支援物理系統,因此定位場景內眾多物件中某一個entity是有困難的,相信未來這不會是個問題,但現在我必須寫很多程式來實現支援ECS的Raycast,因此我採用另外的思維來實現。



首先我在Raycast打到的Collider同樣的座標產生一個只帶有一個DestroyTag的Entity物件,它除了座標之外沒有任何渲染資料,我就可以用System來檢測移除同座標的方塊。同時我也先移除了這個Collider。

我們上面聊了很多關於ECS裡面的E(Entity)和C(Component Data)但一直沒有提到S(System),現在我們要寫一個System來處理刪除方塊的系統。但在之前我想討論這個S和傳統的有什麼不同。傳統的腳本你必須要放到場景內才會隨著物件的Update, FixUpdate或OnCollisionEnter各種方法來運行,但ECS的System是不分場景的,項目內所有的場景只要帶有Entity物件System都會有反應,因此不需要特別把System腳本放入場景物件內。



當然這樣做的好處就是所有的相關系統你可以一隻腳本解決,而不是每個物件有各自的Update方法處理,造成物件數量一大就會影響效能。System不在乎你是一顆子彈或是一隻怪物或是一個角色,只要符合System過濾條件,它都會執行System內的邏輯。

我寫了一個Destroy System用來檢測那些Entity必須要刪除,


System有兩個主要的結構,一個是13-38行代碼的Query,我分別查詢哪些Entity帶有BlockTag和Position,哪些帶有DestroyTag和哪些是地表的花草,然後在OnUpdate內比對哪些事需要刪除的Entity方塊,並檢查上方是否帶有花草需要一並移除。因此這裡總共需要移除的物件有四個:該位置的Entity方塊、作為檢測的Entity物件、地上的花草和BoxCollider物件。



System的OnUpdate也是每幀執行的,你可以從Entity Debugger內看到每個系統的耗時,雖說System是全專案執行的,但你也可以透過API在不同的場景開關這些System。



以上是本次直播快樂的Minecraft ECS製作分享重點內容,後續我們還會有更多的報導。 感謝各位 !

2018年8月6日 星期一

死者之書:(四)Quixel、風、場景地形和優化技巧

作者:Julien Heijmans 原文
潤稿:Wei J


系列作品:
死者之書:(一)概念美術
死者之書:(二)角色資源製作
死者之書:(三)環境資源與特效製作
死者之書:(四)Quixel、風、場景地形和優化技巧


揭秘《死者之書》之Quixel、風、場景製作及優化技巧

嗨!我是Julien Heijmans,在Unity Demo團隊中擔任環境藝術家,我去年才加入Unity不過我已在遊戲產業待了約七年。這篇文章將會從我以《死者之書》的觀點來介紹內容創造者及環境藝術的部分。

攝影製圖對我來說是新的領域,但我清晰地記得多年前Quixel發佈他們用Megascans製作的成果,從那之後我就一直試圖取得使用他們的資源來工作的機會,而加入Unity Demo團隊一起製作《死者之書》使這一切成真了。

如果你想試驗文章裡提到的諸多工具,可以前往AssetStore下載『《死者之書》: 環境』專案。

Unity與Quixel的合作




當我參與進專案後才理解到我們不只是使用Quixel的Megascans資料庫,而是與Quixel公司緊密的合作來進行創作。

在製作過程中,Unity Demo團隊創建了一個所需資源的列表,如果現有的掃描庫中缺少合適的對應資源,Quixel則會為之採集新資源。這其中的不少資源都是植物類型,例如:草地、植栽和灌木叢,這些資源需要合適的設備和佈置來進行掃描。

Quixel不僅為我們提供了資源的紋理集,還創建了相應的幾何體(geometry),帶有LOD(level of detail)和頂點色設置(vertex color),以支持我們的風著色器。



在開發過程中,我們收到了超過50個高質量資源,這些資源較為複雜,我們不得不依靠著團隊中為數不多的藝術家努力在有限的時間中處理完畢。

在製作期間,我們快速的將資源載入到Unity中,得到不錯的外觀效果。我們經常會調整紋理(大多是反光材質(albedo)、亮度/等級/曲線以及修改色彩使它們與場景效果更為統一),重新調整LOD到所希望的等級,並且將紋理指定給一個新的HDRP光照材質。

幸運的是,Quixel發佈了一個工具Megascans Bridge,它能完成之前大量我們需要手工完成的輸入工作。Megascans Bridge為HDRP重打包紋理貼圖節省了大量時間。




如果你對Megascans中資源感興趣,想要獲取更多這類資源, 可以訪問Asset Store獲取。所有這些資源都能夠直接輸入到專案配置中,無論專案使用的是HDRP還是LWRP。






為植被資源及整個管線建立風系統永遠是一個非常棘手的過程。 在場景中,許多不同種類的植被資源需要以不同的方式進行動畫處理,例如:二種不同的樹或許需要完全不同的設置和不同的著色器複雜度。

因此我們決定為了對植被資源產生風效果,做一個基於自訂頂點著色器的程序化動畫。它經過量身打造,適合我們的專案中的樹木或灌木叢。

技術主管Torbjorn Laedre開發了一個著色器,能夠支持多種植被,這個著色器使用了三個不同的技術:

  • 階層軸心(Hierarchy Pivot):應用於樹木和一些擁有非常明確結構/階層的植物。
  • 單一軸心(Single Pivot):應用於草地、小型植物和帶有不確定結構/階層的大型灌木。
  • 程序動畫(Procedural Animation):應用於無法確定軸心點的植被資源。



樹木是準備起來更為複雜的資源,它們使用的是階層軸心類動畫,並且依賴三個不同的層級的階層(levels of hierarchy):


  • 樹幹(Trunk):根植於地面的部分。
  • A級樹枝(Branches Level A):與樹幹相連。
  • B級樹枝(Branches Level B):與A級樹枝相連。

著色器需要知道樹木在階層中的層級和樹木每個頂點的軸心點。首先,我們要編輯樹木本身的幾何圖形,然後使用綠色頂點顏色通道為樹木的每個多邊形指定階層的層級。




  • 頂點顏色的綠色通道數值為0時,表示這個部分是樹幹。
  • 數值在0和1之間則是A級樹枝。
  • 數值為1則是B級樹枝。

我使用了Maya完成這部分任務,通過使用一些小腳本,可以在10-15分鐘內設定好一個資源的所有LOD。

除此之外,我們還使用了飄動遮罩(Flutter Mask)。飄動遮罩是紋理遮罩,能夠幫助判斷樹枝的軸心在幾何體上的位置。下圖是這個遮罩的圖示。


準備好所有資訊後,就可以使用C#腳本來輸入樹木的Prefab,並產生一個新的Prefab,這個Prefab中包含每個頂點的軸心資訊。將WindControl物件加入到場景後,便可以將樹木輸入到場景中,並開始處理材質屬性。



我們可以看到,每個階層層級都具有一個範圍屬性(基本上是樹幹或樹枝長度)和彈性屬性。

還有一些屬性用來設置風抖動(wind flutter )動畫。它們給頂點位置添加了一些程序化的雜訊,用來模仿當風吹到樹幹時的振動效果。

然後我們還需要使風的音效對動畫產生影響。音效的音量會驅使動畫的風力。這是個簡單的想法但加入成果非常驚人,你可以打開專案,然後在場景中四處走動,當聽到大風吹過身邊時,你會發現樹木和周圍的草地都在震動。


佈局

在處理《死者之書》這類專案的細節和密度時,思考如何構層級十分重要,如此能避免在製作中出現的效能問題。其中一個需要顧慮的是關於限制場景中的遠景距離。我們可以通過在場景佈局中放置「過道」(corridor)和「障礙」(bottleneck)來實現這個想法。



這些佈局結合正確設置「Occluder static」和「Occludee static」flag的資源後,會使Unity的遮罩剔除(occlusion culling )更為高效。



上面的影片展示了遮罩剔除的視覺化功能,我們可以看出攝影機是從頂部視圖進行觀察的。在影片結尾,啓用/禁用了遮罩剔除,然後查看哪些物件被遮罩剔除功能所剔除。

我們也能看到一些沒被剔除的物件,這些物件大多是非常高大的樹木,有些超過25米高,這些樹有很大的邊框,因此很難在峭壁後剔除。


使用Unity傳統地形系統(Legacy Terrain)

在《死者之書》預告片發佈後,我們看到有些評論說:這個專案中絕對不可能使用了傳統地形系統。但實際上我們使用的就是傳統地形系統,並且我們修改了HD渲染管線的Layered Lit著色器來支援它。HDRP Layered Lit著色器允許使用高度圖紋理來混合layer,所以得到的結果會比傳統地形著色器的線性混合功能更好。


在此動畫中,僅修改了不同layer的高度偏移(height offset)

當然,這是一種臨時的解決方案,不能在UI中恰當地集成。為了修改地形,我們需要編輯材質用來適用於它,而不是使用在地形物件中Paint Texture tab下的「Edit Texture」按鈕來處理。


這些layer主要是為了幫助繪製地形上的不同layer。它們不是用來渲染地形的,除非是使用平鋪(tiling)設定。


與此相反,尋找適用於地形的材質,我們會發現所有紋理和材質屬性都會影響地形。

如果要創建新地形並在其上應用不同紋理,則需要複製TerrainLayeredLit材質,並將其指定到新地形上。還需要在Paint Texture tab中創建4個紋理集合。指定的紋理不會用來渲染地形,但它們會讓我們在地形上繪制不同的layer,還可以修改不同layer的平鋪設定。

此外,為了能夠充分使用LODGroup功能,所有在地形上放置的資源都會設置為樹木而不是具體的資源。



但實際上,這個專案中有大量零散的資源散布在地面上:草、灌木叢、植物、小樹枝、岩石等。即使有那麼多零散資源,地形仍可以是簡單的,在下一部分我們可以瞭解到,在這個畫面中地形只是一個簡單的平鋪材質。


零散的細節資源

當在關卡中移動時,我們會注意到在地上散落了大量的小樹枝和松果。



如果只是在關卡中隨意移動時,這些並不顯眼,但我們開始注視地面時,這些小樹枝和松果給場景帶來了細節。

有時候地面會有數百根細小的樹枝,分散在岩石和枯萎樹幹之間,這感覺就像它們自然從樹上脫落在這些位置。手工放置它們是不可能的,所以Torbjorn Laedre製作了一個工具幫助我們將這些小型物件分散這些關卡中。

小樹枝是帶有Alpha材質的簡單挖剪(cutout)平面。我們給這些小樹枝添加了膠囊碰撞體(capsule collider)。



腳本首先會在指定位置周圍產生需求數量的零散物件,然後進行落到地面的物理模擬,它們落下後會與地形、其它資源岩石、枯萎樹幹等相互碰撞。然後按下按鈕「Bake」,小樹枝的碰撞體會被移除,合併成單一物件,然後指定給一個帶有特定剔除距離的LODGroup。




此腳本在場景中被用在名為「UberTreeSpawner」的物件上,你可以根據需求隨意使用。

關於此工具的附註:為了使其它零散對象適當地落在地面和其他資源上,在場景中的所有資源皆需要有較高密度的網格碰撞體(mesh collider)。並且在遊戲執行時,這些笨重的碰撞體不能被使用。 出於這個原因,場景中的多數資源帶有兩組不同的碰撞體:一個是輕量的,會被PlayerController用在運行模式的實時環境中,指定在預設的layer。另一個則用於小樹枝的物理效果模擬上,指定於GroundScatter layer。


光照

《死者之書》:環境』專案使用烘焙的間接全域光照(baked indirect global illumination),並帶有即時運算的方向光(real-time direct lighting)

來自太陽的間接光照和來自天空的直接加間接光照都被烘焙到光照貼圖(lightmaps)和光照探針(probe)中。反射探針、遮蔽探針和其它遮蔽來源也會被烘焙。另一方面,直接太陽光直射也是即時光照。在使用即時直接光照時,在HD渲染管線中的著色效果最好,它也能讓我們執行時能自由調整光的方向、強度和色溫。



由於間接光照已被烘焙,我們不能對方向光的強度和顏色進行太多調整,否則它會無法與烘焙光照相符合。儘管樹林能夠掩蓋不符合的間接光照,是個容忍度較大的環境,但我們還是不能在這個設置中脫離完整的晝夜循環。

已烘焙光照貼圖大多用於地形和少數其他資源,但我們更喜歡為專案中的石塊和峭壁使用光照探針和遮蔽探針,因為它們有尖銳的角度和捲曲的法線貼圖,能得到更好的結果。


遮蔽探針(Occlusion Probes)

在即時環境中,難以對茂密的森林進行照明。 樹木的樹葉和樹枝都有巨大的表面積和複雜的幾何形狀,因此給它覆蓋上光照貼圖很不切實際。為每棵樹使用單個光照探針可以從下至上給它一致的光照效果。光照探針代理體積(Light Probe Proxy Volume)能實現更接近我們想要的效果,但通過提高網格解析度來採集精良細節的做法並不實際。

因為這些因素,我們的高級圖形程式設計師Robert Cupisz開發了遮蔽探針。

從美術的角度來看,這是個非常不錯而簡易的功能:只需將物件加入到場景中,它就會顯示一個體積輔助圖示(gizmo)用來縮放,從而覆蓋想要的區域,接著以X、Y、Z來設定它的解析度參數即可。



如果希望場景中某些區域擁有更高密度的探針,它還能允許創建「細節」遮蔽探針。設置完成後,需要烘焙整個場景的光照。遮蔽探針會在這個過程中被烘焙。

通過在上半球發射射線(ray),3D網格中的每個探針會對天空可見度進行採樣,並將其存儲為從完全遮蔽的0到完全可見的1的8位元值。這使得有更高濃度的樹葉和樹枝的地方顯得更黑暗,即使那裡只有幾棵樹聚集在一起也會如此。

落到樹幹或石塊中的探針會完全是黑的。為了避免黑色洩露出來,它們會被標記為無效,並被周圍的有效探針覆寫。

由於探針會對天空的可見部分進行採樣,它們應該要減弱直接來自天空的光照計算部分(direct sky contribution)。所以,光照貼圖會設定成從常規光照探針中排除直接光照(direct light contribution)的計算,然後探針光照由光照探針加上直接天空探針組成,並且都被遮蔽探針所遮擋。

這樣一來我們就獲得了大量低成本的遮蔽探針,會對葉子遮擋天空的細節進行採樣,為圖像帶來深度,我們也得到了少量效能消耗較大的光照探針,用來採集緩慢變化的間接光照。



如果想要更清楚地瞭解它們如何影響場景,可以使用SkyOcclusion Debug視圖進行查看。



這個遮蔽探針API已經加入到Unity 2018.1中,它可以用於烘焙遮蔽探針並從光照探針中排除天空的直接光照計算,專案中的提供了所有腳本和著色器。


大氣散射(Atmospheric Scattering)

我們移植並重新使用了為《Blacksmith》展示Demo所開發的大氣散射(Atmospheric Scattering)解決方案。

我們的高級程式設計師 Lasse Jon Fuglsang Pedersen 對其進行了擴展,讓它可以利用暫時超級採樣(temporal supersampling)功能,使外觀更為平滑。 




HD渲染管線穿透

HD渲染管線的預設發光著色器支援多種漫反射效果。它能讓你得到帶有表面下(sub-surface)散射效果的材質,或就如本專案中為植物所使用的效果,一個更為簡單的只帶有透光性的半透明材質。



此效果設定在兩個不同位置:


  • 我們需要選擇「Translucent」材質類型的材質上,輸入一個厚度(Thickness)貼圖,然後選擇漫反射配置,這個配置文件在第二個位置。
  • 第二個位置是漫反射配置文件設定,我們可以編輯透光效果的其它參數。


注意:我們增加了額外的slider來分別控制直接和間接透光,讓最終結果有更好的可控性。但這個改動並不遵循PBR原則,所以不會被加入HD渲染管線。


Area Volumes

Area Volumes被構築在由SRP提供的核心volume系統上,與Post Process Volumes非常相似。它們的功能根據主攝影機物件的位置修改對象屬性。

包括定向光源、大氣散射、自動聚焦和WindControl在內的多個對象都能受Area Volumes控制屬性,因此,如果想要修改當前的光照設置,則需要在對應Area Volumes中進行操作。那些Area Volume物件在主場景中,位於_SceneSettings > _AREASETTINGS目錄下,帶有「_AV」的後綴字尾。


除錯器視窗

針對不常使用HD渲染管線的使用者,現在有一個特定的SRP除錯視窗,你可以通過選單Window > General > Render Pipeline Debug打開它。





通過這種方式,你可以看到獨立的GBuffer layer、光照組件或是材質中的特定紋理貼圖,甚至是覆寫反光率(albedo)/平滑度(smoothness)/法線(normal)。當一些物件沒正確渲染或是有其它視覺bug時,這是個非常有用的工具。它會幫助你更快找出問題的源頭。

最棒的是這些除錯視圖是從著色器自動生成的,編碼器能夠非常輕鬆地創建新的除錯視圖。


有一些除錯視圖能夠從渲染管線除錯視窗中打開

我們使用這些除錯視圖來創建在場景背景中使用的樹狀billboard。過程很簡單,僅需把資源放到空白場景中,然後進行截圖,截圖時畫面上帶有可見的反光率、粗糙度和法線Gbuffer layer等屬性,然後將它們用來創造自訂的紋理貼圖。


優化

雖然優化的大部分內容屬於程式碼部分,但如果你想要擁有合適的幀率,合理設置好資源和場景也很重要。下面是一些為項目優化內容的方法:


  • 所有的材質都使用了GPU Instancing。
  • 場景中的多數資源都使用了LOD。
  • LOD交叉淡入淡出(The LOD Crossfade)功能很棒,它能夠給不同細節等級的物件帶來好看又平滑的混合效果。但這個功能極度消耗效能,大量提升專案的draw call。因為這個原因,我們大部分的資源都盡可能的禁用。
  • 為了避免LOD之間的過渡區域太過明顯,我們在大型石塊和峭壁資源上使用物件空間(Object Space)法線貼圖。





注意:這裡使用的是物件空間法線貼圖,而不是切線空間(Tangent Space)法線貼圖,這樣做會降低法線貼圖的精確度。實際上,這在我們那些粗糙雜亂的資源上並不明顯,但你或許不會想要把它用在有菱角表面的資源上。


  • 儘管通過建構場景及遮蔽剔除來限制視野距離很重要,同樣值得一提的是,這其中的不少用於渲染場景的draw call消耗實際上來自渲染每個陰影圖的串聯(each cascade of shadow maps),在此專案中特別是來自定向光源(directional light )。
  • 我們有大量draw call來自散落在地形的小型植被資源,有些位置會有上百個draw call。通過將草和植物資源打包,我們減少了大量draw call,現在只剩下15-20。請注意:這會對視覺效果有影響,如此龐大的資源,很難避免草與岩石及其它地上的資源不互相裁切。
  • 我們使用了layer剔除功能,這是Unity中已有的功能,但卻沒有任何UI。此功能允許你根據對象與攝像機之間的距離,剔除被指定為特定layer的對象。Torbjorn擴展了這項功能,使之能夠剔除這些物件在不同距離的陰影投射。例如:我們的大部分小型植被資源會在15米左右停止投射陰影,由於有地面上的草叢和其它植物,這個效果並不明顯,在25米左右的物件會被完全剔除,無它們的LODGroup如何設定。



小結


我們將繼續分享《死者之書》的創作過程,在下篇文章中我們將探索《死者之書》中創建著色、光照和後期處理等內容,盡情關注。

死者之書:(三)環境資源與特效製作

作者:Zdravko Pavlov 原文
潤稿:Wei J

系列作品:
死者之書:(一)概念美術
死者之書:(二)角色資源製作
死者之書:(三)環境資源與特效製作
死者之書:(四)Quixel、風、場景地形和優化技巧



揭秘《死者之書》之環境資源及特效創作

今天將由Unity的Demo團隊的CG和VFX藝術家Zdravko Pavlov帶領大家瞭解攝影製圖資源、樹木以及VFX的創作過程,
Zdravko曾在《Viking Village》、《The Blacksmith》和《ADAM》專案中參與過粒子效果、剛體動力學和布料模擬的創作。

然而《死者之書》則有些不同,這個專案中我需要使用攝影製圖法創建多個環境資源,這是一個全新的領域。戶外攝影是我的興趣, 所以我很樂意接下這份任務,創造一棵樹?我的意思是.......能有多困難是吧?在接下來的內容我會試著描述在前期製作跟開發階段我所學習到的事物。


攝影製圖法(Photogrammetry)工作流程

幸運的是,網絡上有很多關於使用攝影製圖法的有價值的資訊,多數文章會說,你需要任何一台數位單眼及50mm定焦鏡頭。
當時沒有這樣的設備,所以我決定使用自己的2400萬像素 Sony a7II無反相機來做初步測試,這個相機有16mm-35mm變焦鏡頭。但這一切讓我告訴你,是可行的!

寬的鏡頭越會帶來更多的失真,但這些問題總是可以在軟體內修正的,例如使用Lightroom來修,但事實上用不著因為攝影製圖軟體優雅地處理掉了。理論上定焦鏡頭會較為僵硬,並帶來較清晰的圖像。如果你在一個受控的工作室環境中進行掃描,定焦鏡頭的效果很棒。然而在戶外的時候,使用高質量變焦鏡頭妥善地拍攝物體將有助於之後的製作。 












攝影製圖法的一些早期探索。 

我嘗試了多數熱門的攝影製圖軟體,其中一些效果不錯。我選擇的是RealityCapture,因為它具有明顯較優秀的效能,能夠處理大量圖片又不會使記憶體不足。驚人的是還能從圖片中重構大量細節。我由此得到了多個模型,有的模型多達1.85億個三角面,都成功地以PLY格式輸出。





這個數目已經超出了預期,甚至有點極端。多數重構後大約有5000萬~9000萬個三角面。我一開始使用的是GeForce 980Ti顯示卡,後來換成GeForce 1080顯
示卡,為我帶來一些性能的提升。 

我還將相機換成了
4200萬像素的Sony aRII 及PlanarT*FE 50mmF1.4ZA鏡頭。然而兩倍的解析度並使用高級清晰的定焦鏡頭並沒有帶來所期待的驚艷效果。 

一方面,更長也更狹窄的定焦鏡頭意謂著需要退後幾步,才能拍攝重疊的能夠用來重建的畫面。在森林中並不總是能夠往後踏幾步拍攝,因為樹林中還有其它樹木、灌木等障礙。這還代表我們必須管理、存儲和處理原有2倍的GB等級的圖片檔案。儘管如此,還不一定能得到更精確的掃描結果。
精確的掃描來自於更多的圖片,使用2400萬像素將更容易管理。也許這聽起來很理所當然,但我也是親手嘗試後才真正理解這個狀況。


花時間盡可能地獲得更多數據將是值得的

如先前所提到我
輸出的是PLY格式的高密度幾何體。我傾向使用PLY而不是FBX,即使RealityCapture的PLY輸出沒有縮放功能和坐標軸方向控制功能,所以不像FBX,PLY格式文件總會過大、旋轉方向不對。但我選擇自己解決PLY的問題,因為我使用FBX做貼圖烘培時遇到了許多錯誤。 

多數軟體不能處理幾千萬這個數量的多邊形,所以我僅僅存儲文件,使用RealityCapture的抽取功能製作出相同模型的低模版本。得到的模型大概有100萬個三角面。這樣的模型能在Zbrush、MeshLab或其它建模軟體中打開進行重拓撲(retopologized )及展開(unwrapped)。根據不同模型,需要使用了不同的重拓撲方法。經常使用的是Zbrush的ZRemesher,有時候則手動處理。







我使用xNormal來烘焙紋理貼圖。xNormal不會受到數以百萬的三角面影響,可以輕鬆處理它們。我使用頂點顏色(vertex color)資訊來烘焙漫反射紋理。高模的頂點密度完全足夠用來製作乾淨清晰的紋理,不需要任何兩頂點間的插值。 我從未用到RealityCapture的合併展開(integrated unwrapping )及材質功能。

話雖如此,如果因為某些原因你的密度雲不夠密集,或是有區域丟失,如下圖所示,從照片投射紋理可以給這些區域帶來更多細節。


有時候,總會有些區域是人到不了的

多數攝影製圖教學會告訴我們在掃描一個物體時,最好能避免直接刺眼的光照和陰影。如果你要捕獲的是塊小石頭,你可以將它帶到陰涼處或甚至是工作室里,使用柔光箱和轉盤來方便掃描。對於樹木來說則無法這樣做,所以我會查看天氣預報,希望能遇到多雲的天氣。然而即使在陰天,仍會有陰影和環境遮蔽。

這個問題可以通過Unity的DeLighting工具解決。只需要一個法線貼圖、彎曲的法線貼圖和烘焙AO即可。它可以在消除陰影的同時保持漫反射值不變。



Unity的DeLighting工具實際使用效果

處理後的資源接著輸入Unity中,測試動態光照和著色器。








有時候我們不一定能採集到模型的所有部分,也不一定能得到所有角度的畫面。也許會遇到時間不夠或是電量即將耗盡這樣的情況,或是忽略了一些東西,直到回到家開始處理檔案時才發現。我在這個過程中犯了很多這樣的錯誤,但我通過使用Substance Painter來克隆印章工具( clone stamp)試圖修復丟失的數據,挽救了一些作品。






實際遊戲資源

《死者之書》製作的大部分期間是沒有環境美術員工的,部分工作承包給了環境藝術家Tihomir Nyagolov,他對環境進行了初期探索及測試。但主要工作是由創意藝術總監Veselin Efremov和我負責,
我們在附近的森林中採集攝影製圖數據,這些工作自然地轉為最終遊戲資源上來。我沒有環境藝術的背景,對處理遊戲優化、LOD等都毫無經驗。Tihomir Nyagolov使用GrowFx預先創建了一些暫代替換用的樹木,所以我從這裡開始接手工作並從中學習。 

GrowFX做
為創建多種植被的工具是十分強大而功能全面的。它能夠與場景中的其它物件進行互動,所以能夠實現各種獨特而自然的效果。建構時這些物件並不是以資源的形式產生,但也已足夠可控並且足以勝任此項任務。 GrowFX是一個3DS MAX的插件,我做為3DS MAX使用者已經二十多年了,使用起來感到非常的自在。不幸的是,GrowFX依賴MAX中某些過時的組件(component),像是曲線編輯視窗( curves editing dialogs)這類並不是十分方便的功能,但目前來說它對於此項任務來說仍然是個好工具,只能接受這些問題。


《死者之書》中的樹林主要是由針葉樹組成,我家附近正好有些美麗的樹林跟公園,於是我尋找並掃描了一些樹木,然後將GrowFX創作縫合到掃描模型上。最後的樹幹由掃描的模型和獨特的紋理組成,較低部分縫合到了程序化生成樹幹,一直到頂部的剩餘部分則使用可平鋪的(tileable)紋理貼圖。


底部的一小部分被克隆到紋理頂部,使之變成可平鋪紋理

對石塊和樹幹進行攝影製圖是一回事,但掃描松樹的針葉完全又是另一回事了。在這裡便由Quixel介入,Quixel提供了精美的掃描圖集。Quixel的工作人員與我們合作,為《死者之書》製作了大量小型資源,例如:草地、灌木和破瓦殘礫等等。


如我在開頭提到的我擁有CG製作的背景,我曾製作過大型的森林,使用的是Multiscatter或Forest Pack Pro
(同樣是MAX的插件)以及用V-ray做渲染。在那些案例中我們可以使用Quixel 的Megascans圖集,但對於《死者之書》這樣的即時運算專案來說,我們需要多做一些優化。需要優化的內容包括構建大型元素,例如:樹枝、樹頂等等,將這些元素整理成新的紋理,為法線貼圖(normal)、位移(displacement)、透射(transmission)等等轉換初始掃描數據。 





對已有的Megascans法線資料略有修改,偽造出具有體積感的外觀。





我使用不同的法線編輯技術,例如:Normal Thief 和其它自訂3DSMax腳本,用來將樹枝與樹幹混合起來。



修改頂點法線,使之能夠與樹幹混合

通過使用這個方法可以製作不同類型的針葉樹。







我們想要森林富有生氣,而風是一個關鍵元素。我們的環境藝術家Julien Heijmans設計了以頂點著色器為基礎的風動畫方案,樹林是基於這個方案去設置。

創建一個向量場(vector field )有很多不同的方法。在熟悉了Chaosgroup流體處理器和PhoenixFD之後,我決定看看能從中得到哪些可以用的資訊並輸入Unity。我輸出了場景幾何體,以FBX格式放進3DS MAX中執行一些流體效果,流體在植被周圍打轉然後產生了亂流。較大樹木會擋住小型植被,所以效果在這裡不會那麼突出。




PhoenixFD流速通道的一些片段

我使用集成的PhoenixFD回放控制,讓模擬的序列進行
循環

向量資訊通過PhoenixFD Texmap讀取,標準化處理後作為漫反射紋理插入程序化產生的等值曲面(isosurface)。


向量資訊經由PhoenixFD Texmap讀取,標準化處理後作為漫反射紋理插入


一個
水平片段模擬效果範例 

渲染圖像序列將組合成最後的紋理圖集後輸入到Unity中。我過去使用After Effects完成這個工作,但現在Unity擁有一個十分方便的Image Sequencer工具,它能自動完成這個工作。這是由Unity在巴黎的GFX團隊開發的全新VFX工具。


Image Sequencer的實際使用效果

創造出的紋理圖集會放到場景中,我製作了一個小方框用來定義模擬效果的邊界,並用來作為位置的參照(reference)。

這個實驗推動了預告片中一些鏡頭的視覺效果。如果你正使用Unity製作影視作品,我推薦使用這個方法。它會插入主程序的頂點著色器基礎的風動畫方案之中,這個方案是由我們技術主管Torbjorn Laedre開發,它用在預告片中的多個場景中,也有在GDC上展示的主機版本中使用。


後續文章中,Julien和Torbjorn將分享更多關於處理風和最後採用的解決方案。


Unity中的向量場


蜂巢

專案早期我開始對蜂巢的概念進行定調。




使用MultiScatter製作並用V-Ray渲染的概念驗證

在完成最初的設計後,開始建造大量可以在遊戲用的元素使 Unity資源。




使用pflow為蜂巢創建了一些群集




在Unity中組成的早期蜂巢原型

扭奇者(
Screwie)

對於扭奇者群體,我對軀體的變化進行了一些探索。我使用了Chaosgroup的PhoenixFD 進行了流體煙霧模擬。然後切開扭奇者形狀,並基於流體溫度創造了一個等值曲面。





使用PhoenixFD製作的一些形狀探索

這個方法可以快速預覽不同的形狀,做為常規的參考。 扭奇者最後版本的模型是由Plamen (Paco) Tamnev製作,想了解其中驚人的細節可以去看這篇文章

樹液流淌的效果

為了讓扭奇者面部的樹液能夠流動,我再度使用了PhoenixFD。我製作了一個小概念驗證,證明能通過粘稠液體所能實現的效果。


驗證PhoenixFD的翻動處理器能適用於製作液體流動效果

我對整體結果和流體動畫感到滿意,所以繼續對實際模型進行設定。我的目標是防止模擬效果形成太多分離部分。



不同版本的一些樹液流動模擬

我可以得到產生的幾何序列其中一幀,然後對它進行重拓撲,製作UV並使用WRAP3來將其投射到序列中剩下的形狀。最後我得到了一系列使用相同拓撲的blend shapes。


Unity中的Blendshapes

我也嘗試在一些樹幹上運行樹液模擬效果。




我們沒有在最終專案中使用這些效果。然而這是個不錯的方法,可以用來為掃描模型添加一些細節。


小結

《死者之書》中攝影製圖資源、樹木以及VFX的創作過程就分享到這裡,後續我們將深入瞭解《死者之書》中的環境藝術創作過程,盡請關注!

著作人