2017年6月14日 星期三

Unity 5.6中的混合光照詳解

作者:Kemal Akay 原文
潤稿:Kelvin Lo

在Unity 5中,光照得到了很大的改進。現在要打造超逼真的遊戲已成為可能。Adam動畫短片只是證明這種可能性的一個例子。出於對效能的考量,許多Unity開發的遊戲仍然依賴烘焙光照(Baked lighting)。但有時候又必須使用即時和烘焙光照。這在以前會是個問題,在5.6中Unity已解決了這個開發者呼聲很高的需求。

光照功能對新手來說可能比較難懂,因為編輯器預設不會顯示光照設定的介面。而且我們的調查顯示,幾乎所有新手對於光照貼圖都沒有概念。因此,我們改了UI使它更顯眼,不過,有些概念性的知識還是必須要瞭解的。首先簡單介紹即時光照與烘焙光照(光照貼圖)之間的區別。之後再對混合光照進行講解。如果你已熟悉這些概念,可以直接跳過。



何謂預計算即時光照(Precomputed Realtime GI)和烘焙光照(Baked GI)

首先,Unity中新的光照模式沒有為預計算即時GI帶來任何新的內容,而是為開發者提供了可以在場景中同時使用即時與烘焙光照的新方法。即時光照很容易理解,對燈光的任何調整會即時更新場景中的所有光照,唯一的問題是會耗效能。每次調整燈光都會對效能產生很大的影響。因此,Unity同時引入光照貼圖的概念。可以烘焙光照,並將所有光照資料以光照貼圖的形式保存在專案中。這樣做代價很低,因為本質上它只是一個貼圖。

烘焙光照與即時光照的一個主要區別是:烘焙光照都是靜態的,你不能移動這些靜態物件,否則就會出現破綻。將遊戲物件設為靜態物件很簡單,只需要在檢視視窗中將它們標記為static(或只是lightmap static)。這樣Unity會為該物件烘焙光照貼圖。如果你希望物件保持動態,就不要打勾,它們預設就是動態的。



預計算GI – 日夜迴圈


有關這方面概念的詳細介紹已超出本文範圍,而且Unity官網上已有一個由David Llwelyn和光照團隊製作的
系列教學介紹了Unity中使用即時GI光照的優化技巧。

除此之外,我們最近還更新了AssetStore中的Courtyard範例,讓它和Unity 5.5相容。有興趣可以下載試試看,瞭解如何在專案中使用即時光照。


直接光照(Direct light)與間接光照(Indirect light)

許多新手容易忽略的另一個重要概念是,直接光照與間接光照之間的區別。與即時光照類似,直接光的概念也很容易理解。就是從一個光源發射的光射線直接影響一個物體,可以從畫面直接觀察到的。

相對難理解的是間接照明這個概念。基本上,間接照明透過反彈光來實現。除了直接光照,我們還能有反彈的光照。可見光子在一個場景中基於數學公式做簡單的反彈。間接照明的原理如下圖:




透過Light元件的“Bounce Intensity”參數,可以設定一個燈光的間接光貢獻度。換句話說,如果你希望關閉間接光照,可以把這個參數設為0。

所以,預計算即時GI很有趣,能在Unity中發揮的很完美。但是它的代價很高,針對比較低端的設備(例如手機),或是有特別需求的渲染(VR),就需要有更優化的場景設定。然後Unity就會選擇對所有靜態物件進行光照烘焙(例如環境),並對所有動態物件(例如角色)使用即時GI。所以就會產生接下來的問題。


混合光照(Mixed lighting)

從字面上來看混合光照已經說明一切,就是能混合使用即時和烘焙光照。我們所提到的狀況大多數是遊戲會用到的典型狀況。例如在《Last of Us》中,環境場景是固定的,因此它對應的所有東西都儲存在光照貼圖中,而所有移動物件則使用的是即時光照。

可以先烘焙所有環境,然後對角色設定即時光照。但這樣會引發一個嚴重問題:所有的已烘焙物件也會接收動態光源,造成這些物件雙重曝光。當然也可以對這些烘焙物件進行即時光源遮擋,但這樣很容易造成亮度不均。下圖就是這個問題的一個例子。相同材質的相同模型,但其中之一是動態的,另一個是靜態的:



或許這樣你還能勉強接受,但在有些情況下可能就完全走鐘。
此時就該換混合模式登場了。基本上混合模式會幫你處理好一切,平衡範圍內的動/靜態物件亮度(保留視覺逼真度與一致性)。在Unity 5.5中,你可以在檢視面板中將Light Type設為Mixed來啟用混合光照。

那麼現在可以安心的對動態和靜態物件使用混合光照了吧? 
等等……為什麼在這種模式下聚光燈(Spot light)或點光源(Point light),無法投射動態物件的陰影?

原來期望聚光燈能同時影響動態與靜態的物體。到底是我哪裡改錯了還是這是一個Bug?很多開發者會問為何混合聚光燈不會投射任何陰影?

其實原因是混合光照只能
"只有"一個定向光(Directional light)時才能正常工作。

蝦米!你過來我保證不打死你!


Subtractive模式

這就是在Unity中導入新光照模式的主要原因,基本上就是為了解決這個問題。5.6在光照介面中你有四種光照模式可以選擇。它們是Baked Indirect, Distance Shadowmask, Shadowmask以及Subtractive。只有三項新的光照模式加入。其中Subtractive算是舊的混合模式,與其他模式相比它的效能消耗要小,這在開發像是手機專案時仍有點用處。

讓我們用Unity的技術術語來重新描述下這個模式的工作原理:選擇‘Mixed’烘焙模式,標記為靜態的物件會把來自混合燈光的資訊保存為光照貼圖。但與標記為‘Baked’的燈光不同,混合燈光還會為場景中的動態物件提供即時光照。前面提到只有單個定向光時它才能正常工作對吧?沒錯,因為混合點光源和聚光燈不會在物件上投射任何陰影。

此外,Subtractive模式裡還有一個特別的功能。它與其他模式不同,直接光照也是烘焙的,因此在Subtractive光照模式中,沒法有鏡面反射。


探針遮蔽(Probe Occlusion)

在Subtractive模式中,另一個動態物件需要使用的重要元件是光照探針組(Light probe groups)。沒有光照探針,動態物件就無法對用在靜態物件的光照進行採樣,更重要的是它們無法使用遮擋資料。因此為了能接收陰影,動態物件需要將來自光照探針的光照進行混合。在下面的圖像中,你能看到一個動態物件是如何利用光照探針做遮蔽的。


為了實現更精確的遮擋,可以為場景中重要的物件(例如主要角色)指定光照探針代理(LPPV)。但是要注意這會帶來額外的效能消耗。

色彩空間與Subtractive模式中的渲染路徑

關於Subtractive模式還有一點需要提一下。這個模式是為Forward 渲染模式和Gamma顏色空間設計的。不適用於Deferred 渲染模式和Linear顏色空間。因為Subtractive模式與其他模式相比,效能消耗相對要小,主要用於像手機這樣的低階設備。有關渲染路徑(Rendering paths)和色彩空間(Color space)的資訊可以在官方手冊中查看。


新的光照模式Distance Shadowmask, Shadowmask 和Baked Indirect

Unity對Shadowmask的支援是新混合光照模式中的一個重要新功能。此外,還有密度與方向性貼圖,Unity現在能為所有的光照類型生成Shadowmask了。與Subtractive模式不同,Shadowmask可以將所有光照類型的即時與烘焙陰影無縫混合。這表示我們可以獲得遠距離陰影。出於效能考量,可以在近處使用即時陰影而遠處使用烘焙陰影,來保持更低的Draw Call。與Subtractive模式相反,Shadowmask功能還可以產生高品質的即時鏡面高光。除了這些功能外,我們還對UI做了改進與重建,加了新的除錯模式來協助你更好的在場景中設定光照。

這個影片顯示了用Shadowmask 和Distance Shadowmask的效果。預計算即時GI在這個場景設定中已完全關閉。


我們已經說過Subtractive模式就是Unity中舊的Mixed模式。除此之外,Lighting Mode介面中還有兩個新的選項: Baked Indirect 和Shadowmask。要重點注意的是,Baked Indirect和Shadowmask不是品質設定。所有模式都有自己獨特的功能特性,它們能在不同的場合中發揮不同的作用。

Shadowmask的主要功能本質上非常容易理解,它可以解決Subtractive無法完成的事情。Shadowmask不僅能處理方向光,還可以使用點光源和聚光燈混合即時與烘焙陰影而不會增加雙重陰影/光照,意思就是可以正確合成重疊的陰影。


在繼續之前,我們需要先定義陰影距離的概念,它與光照模式息息相關,但許多新手不知道這個概念。要正確有效的製作場景,就必須要掌握這個觀念。否則很容易就會碰到不必要的draw call和FPS下降。


陰影距離(Shadow Distance)和陰影投射物(Shadow Casters)的概念

在Unity中,陰影的行為由陰影距離和光照模式決定。查看陰影距離的一種快速方式就是使用Shadow Cascades模式。在場景視圖中可以選擇Shadow Cascades模式來顯示陰影距離。這個參數可以在Quality設定中修改。你也可以用程式呼叫API來更改陰影距離,只不過使用場合相當有限。不過它在某些極端情況下會有作用(例如當需要在某些光照模式中為了降低draw call而減少陰影距離)。


因此,物件在陰影距離之內還是之外,會影響陰影的行為,並對效能產生直接影響。

實際上,如果打開Quality設定(Edit > Project Settings > Quality),會發現有很多參數可用來調整陰影的設定。很可惜這些設定被藏在這裡,大部分開發者都不知道它們的存在,除非在需要時搜索到這些參數。

尤其是可以在Distance Shadowmask和Shadowmask之間切換的Shadowmask功能選項。預設的是Distance Shadowmask選項,接下來會討論這兩個模式之間的區別。讓我們先從Shadowmask開始。

Shadowmask

在Shadowmask模式中,靜態物件透過Shadowmask從其他靜態物件接收陰影,不必考慮陰影距離。來自動態物件的陰影只能透過陰影距離內的陰影貼圖獲得。動態物件透過陰影距離內的陰影貼圖接受來自其他動態物件的陰影。來自靜態物件的陰影僅能通過光照探針獲得。

現在,當你同時在動態物件和光照貼圖靜態物件上使用Shadowmask模式時,首先你可能會發現問題就是,動態物件的陰影(Shadow maps)和來自光照貼圖靜態物件的烘焙陰影不一致。Unity 5.6在執行時只支持簡單版本的PCF( Percentage Closer Filtering )陰影,這種陰影很簡陋,走近時還可能會出現陰影瑕疵。因此,動態物件是不可能獲得軟陰影(Soft Shadow)的。與之相比,靜態物件則相對較容易獲得軟陰影。實際上,通常需要增加解析度以渲染更多靜態物件的陰影,因為你需要更多的貼圖圖元來定義一張光照貼圖上的陰影。只有這樣,你才能渲染出與來自動態物件的陰影貼圖相近的陰影。


你可以看到,使用高解析度光照貼圖,來自靜態物件的烘焙陰影與來自動態物件的陰影貼圖已十分接近。


使用低解析度的光照貼圖,來自靜態物件的烘焙陰影與來自動態物件的陰影貼圖明顯不同。

關於Shadowmask模式的一個友善提示:動態物件只會在陰影距離內投射陰影貼圖。而靜態物件,無論陰影距離是多少,只會投射烘焙陰影。Shadowmask 和Distance Shadowmask兩者均可提供即時鏡面高光。

那麼問題來了,什麼是Distance Shadowmask?它與Shadowmask有何不同?



Distance Shadowmask

普通的Shadowmask模式要比Distance Shadowmask模式產生更少的Draw Call。為什麼呢?

這是因為Distance Shadowmask的行為是由陰影距離決定的。在陰影距離內,動、靜態物件都會渲染進陰影貼圖,靜態物件可以在動態物件上投射銳陰影。超出陰影距離,靜態物件會通過預計算Shadowmask接收來自其他靜態物件的高品質陰影,而動態物件則通過光照探針與LPPV,接收來自靜態物件的低解析度陰影。

這樣應該能解釋清楚Distance Shadowmask模式下動、靜態物件的陰影投射方式以及為何Shadowmask模式要比Distance Shadowmask模式資源消耗更少了。基本上,陰影貼圖的效能消耗要高於烘焙陰影(因為它們在每幀都進行渲染,而烘焙陰影是保存在一個貼圖/光照貼圖中的)。

在Shadowmask模式下,動態物件只會在陰影距離內投射陰影貼圖。Distance Shadowmask的效能消耗更大,因為靜態物件也可以在陰影距離內投射即時陰影貼圖,這樣會使Draw Call增加。這也就是為什麼Distance Shadowmask模式更適合高階PC或遊戲主機的專案。而Shadowmask則作為一種廉價的解決方案,在中低階設備使用。

Shadowmask中的遮蔽

有關Shadowmask的功能,我還想就不同物件類型遮蔽的工作原理進行詳細說明。本文我們談到了為何光照探針的放置位置對於動態物件接收來自靜態物件的陰影如此重要。本質上,動態物件需要光照探針從遮蔽物採樣遮蔽資料。因此,Subtractive模式中的探針遮蔽概念同樣可以直接適用於Shadowmask和Distance Shadowmask。

有關物件是如何根據類型與光照模式接收對應陰影的快速參考可以查看光照模式參考卡(Lighting Modes Reference Card),也可以列印出來以備不時之需。



作為Quality設定的Shadowmask

在Unity 2017.1中,Shadowmask和Distance Shadowmask選項被移到了Quality設定中,這麼做的原因有兩點。

首先,我們希望開發者能對陰影行為能有更多創意的控制,所以可以在執行時對模式進行切換。例如,你可以在同一場景中的室內環境使用Shadowmask(比如在機庫中實現軟陰影),在室外環境時切換到Distance Shadowmask。事實上,我有另外一篇文章來說明如何用API來實現。

其次,可以針對不同的硬體設定不同的要求。例如在遊戲中的設定頁面,可以顯示一個玩家可以調整的設定選項,如果你要發佈遊戲到Steam,可以在低階硬體上使用普通的Shadowmask,在高階PC上使用Distance Shadowmask。

之所以能這樣隨心所欲進行設定,是因為技術上在Shadowmask 和Distance Shadowmask之間的切換非常簡單,唯一的缺點就是Draw Call的數量,但不管怎麼說,最後都是取決於開發者。


技術限制和調試工具

最後,讓我們聊聊Shadowmask功能(Shadowmask 和Distance Shadowmask)的技術限制,以及能幫你在設定過程中進行問題診斷的除錯工具。

你已知道如何和為何使用Shadowmask,讓我們來聊聊它的限制。由於技術約束,在一個場景中,Unity僅支援4個重疊的混合燈光。如果在相同位置有超過4個的混合燈光,其中之一就會降級為烘焙。通常如果你看到其中有某個燈光突然爆亮,大概就是因為這個。

還好我們有個視覺化除錯工具可以幫你解決問題。如果將場景的visualization模式從“Shaded”切換到“Light Overlap”,你可以看到問題區域顯示為亮紅色。

值得一提的是,與點光源或聚光燈不同的是,方向光沒有定義的邊界,它是全方向的。因此,你在除錯重疊的混合燈光時,總要將它考慮在內。在螢幕上,你可能只看到4個重疊燈光,但實際上,方向光可能已在某些位置與之有了交疊。如果在場景中使用了多個方向光來進行照明(例如補光),那情況就有點麻煩了,所以小心使用它。



Baked Indirect

目前為止我們已經介紹了Subtractive模式、Distance Shadowmask和Shadowmask功能。還剩最後一個模式,Baked Indirect。

與Shadowmask複雜的選項相比,Baked Indirect模式相當容易理解。Baked Indirect沒有使用任何Shadowmask。所以在這個模式中沒有遠距離陰影。在陰影距離之內,所有靜態和動態的物件都投射 即時陰影貼圖。但超出陰影距離後,就沒有陰影。

在Baked Indirect中,除了間接照明之外所有的東西都是即時的。這代表即時光照、即時陰影以及即時鏡面高光,但是反射的光照資訊儲存在光照貼圖中是靜態的。在這個模式中,你能做的事情有限,但是你可以用它來做些很有創意的事情。下面你會看到搖擺的Baked Indirect模式混合聚光燈,是如何偽造即時全域照明的。


你可以看到燈光在變化,亮度忽明忽暗。但如果你仔細觀察街燈的間接照明,你會發現它並沒有變化。所以從技術上來說,你可以移動你的燈光,但不能太多,否則會出現陰影瑕疵。在下面的影片中,你會看到在場景中移動物件時,間接照明是如何導致這種類型陰影瑕疵的:



關於Unity 5.6中的混合光照就介紹到這裡,我們會不斷的為大家繼續翻譯分享從Unity官方部落格的技術文章!

2017年6月7日 星期三

iOS和macOs上的XR

作者:Scott Flynn, 原文

Unity的三大宗旨之一就是讓開發普及化,我們也關心著VR/AR行業相關的最新消息,期望全球開發者們將創意變為現實。

在6月6日的WWDC上,Apple首次公開展示了iOS對AR以及macOS對VR的支援。開發者將可以用整合ARKit的Unity直接為iOS設備開發AR應用,並且可以為macOS平台建立360全景影片以及VR內容。我們也非常興奮能與Apple合作來共同擴展VR/AR生態,確保XR(VR、AR、MR統稱為XR)行業能讓全球社群隨手可得。

現在Unity也推出了可用於在macOS平台上製作VR內容的體驗版,並在BitBucket上放了開源的Unity ARKit套件。

Unity滿足大家對於VR及AR內容開發的期望,能夠支援在Mac版的Unity編輯器中直接測試XR應用並快速反覆運算。使用這個VR體驗版已經可以製作內容並發佈至App Store。我們也找了一些開發者一起來測試這個版本,以下是他們的反饋:

“除了將專案升級為最新的Unity體驗版之外,幾乎毫不費力就可以將PC端的VR遊戲完美移植到macOS平台”
-- Zack Brown, Zulubo Productions


“整體來說,使用Unity將《Space Pirate Trainer》移植到macOS平台的過程非常流暢。我們讓它在macOS系統上跑了好幾個小時。之前我對Metal支持還有些猶疑,但Unity與Apple讓整個流程相當簡潔。過去幾個月裡Unity對Metal的支持進行了大量優化,並且支援很多自訂著色器,儘管在建立這些著色器時並非從Metal的角度出發。Unity、Valve及Apple都做得非常出色!”

– Dirk Van Welden, I-Illusions


macOS平臺Unity編輯器VR模式運行Space Pirate Trainer


在這個Unity體驗版中,我們與Apple及Valve共同合作對Metal 2進行了優化,以符合目前的VR渲染通道、Multi-Pass以及Single-Pass和Variants。在最初的版本中,我們利用WWDC上公佈的Metal 2新功能結合Instancing獲得了顯著的效能提升,而需要的Draw Call數量更是直接減半。


使用Unity為macOS開發VR應用

我們希望所有想在macOS平台上開發VR內容的開發者都來試用這個體驗版並給我一些反饋,協助我們改善產品品質。和所有Unity體驗版一樣,在進行升級之前請務必備份您的專案!


硬體及軟體需求:

  • 從論壇下載Unity XR體驗版,這個版本會包含開啟VR模式的選項,並加了OpenVR平臺。
  • 您將需要支援macOS的SteamVR套件。可以到Valve官網瞭解更多詳情
  • 為macOS開發VR內容需要系統版本為macOS High Sierra。該版本包含大量驅動與Metal優化,能最大化發揮硬體的潛能。
  • 與所有VR內容一樣,硬體品質會決定最終內容的品質。對於3D的VR內容開發建議使用Radeon Pro 500系列顯卡。



使用ARKit

我們在BitBucket提供了Unity ARKit套件,可以從論壇找下載。這個Unity套件將讓開發者們輕鬆使用ARKit的功能,例如世界追蹤(World Tracking)、即時影片渲染(Live Video Rendering)、平面預測與更新(Plane Estimation and Updates)、碰撞檢測API(Hit-testing API)、環境光預測(Ambient Light Estimation)以及原點雲資料(Raw Point Cloud Data)。


Unity中可以直接透過C#腳本API存取所有ARKit公開的功能介面。同時還提供了Unity腳本以便於為現有Unity遊戲專案整合這些新功能。請查閱BitBucket中Unity-ARKit-Plugin專案說明文件瞭解更多資訊。

硬體及軟體需求如下:

  • 使用Unity ARKit套件需要Unity 5.6.1p1及以上版本。同時也支援上述的體驗版。
  • iOS 11及以上版本
  • XCode 9 beta及以上版本,並且需要包含ARKit框架的iOS SDK
  • ARKit框架能夠支援的iOS設備

著作人