今天為大家分享
unity與Alex Lovett共同使用
unity5制作的Shrine Arch-viz Demo,其中充分利用了Unity5的實時全局光照功能。實在是太過驚艷,隨便一幀都可以直接拿來當做屏保~~~
上面的Demo使用Unity5.2制作,沒有導入任何第三方資源包,從無到有歷時8周。
全實時光照的場景
整個Demo全是實時全局光照(下簡稱GI),沒有使用烘焙。場景包含了一天的各個時刻、大量集合圖形、100來個晚間出沒的點光源、一些流光、一些固定支架上的探照光以及可選的閃光燈。晝夜交替的效果是使用天空盒同步太陽運動來實現的,以便捕捉不太明顯的光照變化。在Demo中,你可以通過UI自己控制上述所有的光照。
下面欣賞一下Demo的畫面:












這個場景對光照有特別要求。有些地方在白天或日落后都只依賴反射光來照亮。
整個實時GI系統是通過預先計算場景中所有靜態物體之間的光線路徑來實現的。這樣一來就可以實時調整光照而不會中斷,因為系統已經有了計算光照變化序列的所有信息。但這也意味着場景中的靜態物體不能移動,因為動過之后需要重新計算所有路徑。所以整個制作過程都是先制作幾何體然后添加光照(必要時重復)。不經意地移動幾何體並同時調整光照可能會導致多次計算光照信息。
實時GI創作
上面的效果很震撼吧,但這只能在PC或主機上運行,要想在移動端運行還得經過一些改造。
Unity5中的實時GI利用了Geomerics公司的Enlighten技術,並專為游戲設計。所有的光照計算都是由CPU工作線程異步執行的,由於游戲通常是GPU綁定的,額外的CPU工作對整體幀率的影響很小。而且也只有那些有光照變化的區域需要重新計算。
游戲中的光照延遲是由選取的實時間接光照貼圖分辨率決定的。而Alex為了保證響應迅捷,在Demo中將分辨率設得相當低,即便這樣還是有些間接光照的地方並未完全達到想要的效果。
間接光照貼圖分辨率如下:
- 中央區域兩單元一個紋理像素(即每單元0.5紋理像素)
- 沙漠里接近中央區域的位置10單元一個紋理像素
- 沙漠外部區域32單元一個紋理像素
為了使分辨率平均,整個場景采用了平均每個單元0.25紋理像素的做法,下圖分別是UV圖(表示間接光照貼圖分辨率):

Clusters(負責反射光的發射):

反射光貼圖:

以及光照方向貼圖:

保證光照貼圖UV的效果比較重要。某些情況下要非常小心以確保模型在編輯器模式和運行模式下都能正常工作。典型的例子就是樓梯。
樓梯照明表現正常是有難度的,因為尺寸較大的紋理像素可以覆蓋多個階梯。這會導致光照層次夾在階梯之間。另一方面,由於性能
問題也不能為階梯使用多個紋理像素。此場景中的樓梯是有斜面的,它會浪費很多紋理像素空間。最初樓梯實時GI的UV布局如下:

其中使用了70x72紋理像素的光照貼圖。這個布局有兩個問題,首先是每個階梯用的紋理像素太多(4x4);其次被分離到兩張圖中的斜面也會占用至少4x4的紋理像素。
Enlighten在運行時處理紋理是以2x2的單位來優化的,所以每張圖需要至少2x2的紋理像素。另外,Enlighten包含了無縫銜接功能,圖片會自動被銜接到一起以便保證圖像更平滑,例如球體和圓柱。這個功能要求各圖在邊緣部分有單獨的方向信息。方向信息只保存在各個塊中,所以銜接過的圖需要至少2x2個塊,加起來就是4x4的紋理像素。此樓梯中不需要進行銜接,所以2x2的紋理像素就可以滿足需求。
在光照面板中新加入了最小圖尺寸的選項:

這個值可以設為4用於銜接用到方向的貼圖,或者設為更緊湊的2,可以大大降低紋理像素密度,這時樓梯模型只需44x46紋理像素的光照貼圖即可:

此時樓梯斜面還是霸占了一些不必要的空間。下圖展示了模型的UV邊界。注意整個斜面集成到了階梯中:

光照貼圖UV的
2D視圖中並未出現斜面,因為斜面被整個疊在了階梯中。這樣做的目的是避免光照模擬會考慮到被遮擋的斜面。

斜面之所以被分為兩張圖是因為用於實時GI的UV會按照各對象用到的實際分辨率重新打包。打包算法會默認各圖會有0.5紋理像素的邊界,這樣可以避免圖像失真。也保證了對圖集的充分利用,同時不需為各具體UV打包邊緣。
邊緣越鋒利帶來的問題越明顯,此例中樓梯與斜面的邊緣就是如此。模型導入器會自動復制鋒利邊緣處的頂點,因為邊緣兩邊需要不同的法線。所以貼圖會在外部分離。重新打包會導致斜面貼圖分離。因為貼圖默認使用法線來檢測。當它找到頂點位置、UV完全一樣但法線不同的邊緣,就會按照邊緣分離貼圖。
此例中不需如此。斜面會被集成到階梯的貼圖中,因為它對光照沒有實際影響。所以為了實現這點,同樣在光照面板中新增了Ignore Normals,以便在打包階梯期間進行貼圖檢測時忽略法線。這樣可以聚合UV貼圖而不用在乎邊緣:

選中Ignore Normals會進一步減小紋理像素密度。此時斜面已被集成到樓梯中。最終的光照貼圖是22x24紋理像素:


使用這些選項可以將實時GI預計算的時間從1.5小時直接縮短至15分鍾。
關於性能
實時GI在滿足其運行性能與內存需求的情況下不需要太多調整。然而,后期特效特別多,其中包括Filmic Vignette(電影修飾), Bloom(爆發),Tonemapping(色調映射),Lens Distort(鏡頭變形),Screen Space Ambient Occlusion(屏幕空間的環境光遮蔽),Color Correction Curves(顏色校正曲線),Noise And Grain(噪聲及噪點),Color Grading Properties(顏色漸變)以及 Antialiasing(抗鋸齒)等等。除開這些可以在PC上運行時達到60fps。
快速環境光
實時GI系統可以使用天空盒直接驅動環境光輸入。但使用該功能需要先從GPU獲取天空盒紋理以便基於實時GI系統更新CPU。這在環境光每幀都會發生變化的情況下非常不理想。所以替代方法是,由當前時間來控制環境光,並轉換為關照漸變和環境光強度用於驅動實時GI系統。這些都可以在光照面板中設置:

漸變環境光源可以完全由CPU來處理。這樣處理的效果與完全使用天空盒幾乎看不出差別。

用於更新環境光的核心代碼如下:
[AppleScript]
純文本查看 復制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
usingSystem;
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
[ExecuteInEditMode]
publicclassEnvironmentUpdater
:
MonoBehaviour
{
publicGradient groundGradient
,
equatorGradient
,
skyGradient;
privateTimeOfDayManager m_TimeOfDayManager;
voidOnEnable
(
)
{
m_TimeOfDayManager
=
FindObjectOfType
<
timeofdaymanager
>
(
)
;
}
voidUpdate
(
)
{
floatcurrentTime
=
m_TimeOfDayManager.time;
RenderSettings.ambientGroundColor
=
groundGradient.Evaluate
(
currentTime
)
;
RenderSettings.ambientEquatorColor
=
equatorGradient.Evaluate
(
currentTime
)
;
RenderSettings.ambientSkyColor
=
skyGradient.Evaluate
(
currentTime
)
;
}
}
|
快速發射光
與環境光類似,實時GI系統可以根據發光着色器屬性直接驅動發光物體。默認會使用發射光材質屬性,或添加自定義着色器通道,在實時光照貼圖空間渲染出一張發射光貼圖。這需要在實時GI系統消滅數據之前從GPU下載紋理。可以在腳本中使用(DynamicGI.SetEmissive)將物體的發射光屬性設為固定的顏色,並允許實時GI系統在模擬GI中直接使用發射光。這樣可以完全繞過GPU,且幾乎不需要什么代價就可以照明場景。

關於大場景中的GI
可以對大場景采取流式加載以保證內存消耗低同時快速響應。實時GI系統可以結合LoadLevelAdditive和UnloadLevel使用。當然在加載關卡時有些注意事項,因為關卡並非加載后直接可見,所以可能會影響到反射光。
其它的加載方式,或多場景編輯的功能會在12月8日發布的Unity5.3中提供,那時通過實時GI系統縮放場景中的光照就很容易了。
今天為大家分享
unity與Alex Lovett共同使用
unity5制作的Shrine Arch-viz Demo,其中充分利用了Unity5的實時全局光照功能。實在是太過驚艷,隨便一幀都可以直接拿來當做屏保~~~
先奉上視頻:
上面的Demo使用Unity5.2制作,沒有導入任何第三方資源包,從無到有歷時8周。
全實時光照的場景
整個Demo全是實時全局光照(下簡稱GI),沒有使用烘焙。場景包含了一天的各個時刻、大量集合圖形、100來個晚間出沒的點光源、一些流光、一些固定支架上的探照光以及可選的閃光燈。晝夜交替的效果是使用天空盒同步太陽運動來實現的,以便捕捉不太明顯的光照變化。在Demo中,你可以通過UI自己控制上述所有的光照。
下面欣賞一下Demo的畫面:












這個場景對光照有特別要求。有些地方在白天或日落后都只依賴反射光來照亮。
整個實時GI系統是通過預先計算場景中所有靜態物體之間的光線路徑來實現的。這樣一來就可以實時調整光照而不會中斷,因為系統已經有了計算光照變化序列的所有信息。但這也意味着場景中的靜態物體不能移動,因為動過之后需要重新計算所有路徑。所以整個制作過程都是先制作幾何體然后添加光照(必要時重復)。不經意地移動幾何體並同時調整光照可能會導致多次計算光照信息。
實時GI創作
上面的效果很震撼吧,但這只能在PC或主機上運行,要想在移動端運行還得經過一些改造。
Unity5中的實時GI利用了Geomerics公司的Enlighten技術,並專為游戲設計。所有的光照計算都是由CPU工作線程異步執行的,由於游戲通常是GPU綁定的,額外的CPU工作對整體幀率的影響很小。而且也只有那些有光照變化的區域需要重新計算。
游戲中的光照延遲是由選取的實時間接光照貼圖分辨率決定的。而Alex為了保證響應迅捷,在Demo中將分辨率設得相當低,即便這樣還是有些間接光照的地方並未完全達到想要的效果。
間接光照貼圖分辨率如下:
- 中央區域兩單元一個紋理像素(即每單元0.5紋理像素)
- 沙漠里接近中央區域的位置10單元一個紋理像素
- 沙漠外部區域32單元一個紋理像素
為了使分辨率平均,整個場景采用了平均每個單元0.25紋理像素的做法,下圖分別是UV圖(表示間接光照貼圖分辨率):

Clusters(負責反射光的發射):

反射光貼圖:

以及光照方向貼圖:

保證光照貼圖UV的效果比較重要。某些情況下要非常小心以確保模型在編輯器模式和運行模式下都能正常工作。典型的例子就是樓梯。
樓梯照明表現正常是有難度的,因為尺寸較大的紋理像素可以覆蓋多個階梯。這會導致光照層次夾在階梯之間。另一方面,由於性能
問題也不能為階梯使用多個紋理像素。此場景中的樓梯是有斜面的,它會浪費很多紋理像素空間。最初樓梯實時GI的UV布局如下:

其中使用了70x72紋理像素的光照貼圖。這個布局有兩個問題,首先是每個階梯用的紋理像素太多(4x4);其次被分離到兩張圖中的斜面也會占用至少4x4的紋理像素。
Enlighten在運行時處理紋理是以2x2的單位來優化的,所以每張圖需要至少2x2的紋理像素。另外,Enlighten包含了無縫銜接功能,圖片會自動被銜接到一起以便保證圖像更平滑,例如球體和圓柱。這個功能要求各圖在邊緣部分有單獨的方向信息。方向信息只保存在各個塊中,所以銜接過的圖需要至少2x2個塊,加起來就是4x4的紋理像素。此樓梯中不需要進行銜接,所以2x2的紋理像素就可以滿足需求。
在光照面板中新加入了最小圖尺寸的選項:

這個值可以設為4用於銜接用到方向的貼圖,或者設為更緊湊的2,可以大大降低紋理像素密度,這時樓梯模型只需44x46紋理像素的光照貼圖即可:

此時樓梯斜面還是霸占了一些不必要的空間。下圖展示了模型的UV邊界。注意整個斜面集成到了階梯中:

光照貼圖UV的
2D視圖中並未出現斜面,因為斜面被整個疊在了階梯中。這樣做的目的是避免光照模擬會考慮到被遮擋的斜面。

斜面之所以被分為兩張圖是因為用於實時GI的UV會按照各對象用到的實際分辨率重新打包。打包算法會默認各圖會有0.5紋理像素的邊界,這樣可以避免圖像失真。也保證了對圖集的充分利用,同時不需為各具體UV打包邊緣。
邊緣越鋒利帶來的問題越明顯,此例中樓梯與斜面的邊緣就是如此。模型導入器會自動復制鋒利邊緣處的頂點,因為邊緣兩邊需要不同的法線。所以貼圖會在外部分離。重新打包會導致斜面貼圖分離。因為貼圖默認使用法線來檢測。當它找到頂點位置、UV完全一樣但法線不同的邊緣,就會按照邊緣分離貼圖。
此例中不需如此。斜面會被集成到階梯的貼圖中,因為它對光照沒有實際影響。所以為了實現這點,同樣在光照面板中新增了Ignore Normals,以便在打包階梯期間進行貼圖檢測時忽略法線。這樣可以聚合UV貼圖而不用在乎邊緣:

選中Ignore Normals會進一步減小紋理像素密度。此時斜面已被集成到樓梯中。最終的光照貼圖是22x24紋理像素:


使用這些選項可以將實時GI預計算的時間從1.5小時直接縮短至15分鍾。
關於性能
實時GI在滿足其運行性能與內存需求的情況下不需要太多調整。然而,后期特效特別多,其中包括Filmic Vignette(電影修飾), Bloom(爆發),Tonemapping(色調映射),Lens Distort(鏡頭變形),Screen Space Ambient Occlusion(屏幕空間的環境光遮蔽),Color Correction Curves(顏色校正曲線),Noise And Grain(噪聲及噪點),Color Grading Properties(顏色漸變)以及 Antialiasing(抗鋸齒)等等。除開這些可以在PC上運行時達到60fps。
快速環境光
實時GI系統可以使用天空盒直接驅動環境光輸入。但使用該功能需要先從GPU獲取天空盒紋理以便基於實時GI系統更新CPU。這在環境光每幀都會發生變化的情況下非常不理想。所以替代方法是,由當前時間來控制環境光,並轉換為關照漸變和環境光強度用於驅動實時GI系統。這些都可以在光照面板中設置:

漸變環境光源可以完全由CPU來處理。這樣處理的效果與完全使用天空盒幾乎看不出差別。

用於更新環境光的核心代碼如下:
[AppleScript]
純文本查看 復制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
usingSystem;
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
[ExecuteInEditMode]
publicclassEnvironmentUpdater
:
MonoBehaviour
{
publicGradient groundGradient
,
equatorGradient
,
skyGradient;
privateTimeOfDayManager m_TimeOfDayManager;
voidOnEnable
(
)
{
m_TimeOfDayManager
=
FindObjectOfType
<
timeofdaymanager
>
(
)
;
}
voidUpdate
(
)
{
floatcurrentTime
=
m_TimeOfDayManager.time;
RenderSettings.ambientGroundColor
=
groundGradient.Evaluate
(
currentTime
)
;
RenderSettings.ambientEquatorColor
=
equatorGradient.Evaluate
(
currentTime
)
;
RenderSettings.ambientSkyColor
=
skyGradient.Evaluate
(
currentTime
)
;
}
}
|
快速發射光
與環境光類似,實時GI系統可以根據發光着色器屬性直接驅動發光物體。默認會使用發射光材質屬性,或添加自定義着色器通道,在實時光照貼圖空間渲染出一張發射光貼圖。這需要在實時GI系統消滅數據之前從GPU下載紋理。可以在腳本中使用(DynamicGI.SetEmissive)將物體的發射光屬性設為固定的顏色,並允許實時GI系統在模擬GI中直接使用發射光。這樣可以完全繞過GPU,且幾乎不需要什么代價就可以照明場景。

關於大場景中的GI
可以對大場景采取流式加載以保證內存消耗低同時快速響應。實時GI系統可以結合LoadLevelAdditive和UnloadLevel使用。當然在加載關卡時有些注意事項,因為關卡並非加載后直接可見,所以可能會影響到反射光。
其它的加載方式,或多場景編輯的功能會在12月8日發布的Unity5.3中提供,那時通過實時GI系統縮放場景中的光照就很容易了