當前位置:首頁 >教程首頁 > Unreal Engine >UE4手遊如何渲染與優化環境反射?

UE4手遊如何渲染與優化環境反射?

發布時間:2020-11-02 14:46:05

今天跟大家分享下UE4手遊如何渲染與優化環境反射?!本文介紹了四個小主題,分別是UE4 Mobile端的Skylight和ReflectionCapture之間的關係,如何讓ReflectionCapture采集天光,ReflectionCapture的亮度校正算法分析及在期在移動端可能的優化。值得一提的是ReflectionCapture IBL的壓縮是UE4.26中已被實現。

這篇文章是UE4 反射球係列文章的完結篇,內容包含以下幾個部分:

1. SkyLight和Reflection Capture的Cubemap有何不同?

2. Reflection Capture為何采集不到天空球Mesh?

3. Reflection Capture的亮度是如何確定的?

4. 對移動端來說,Skylight/Reflection Capture有哪些可用的優化?

一、SkyLight和Reflectioin Capture

SkyLight所提供的是直接光照,同時包含漫反射和高光反射,而Relfection Capture提供的是環境反射,隻有間接高光且不包含漫反射。嚴格來說,這兩部分光照信息的頻度定位不同,是疊加關係,不能放一起比較。

凡事都有意外,UE4在移動端的標準光照模型中SkyLight Cubemap和Reflection Capture Cubemap是互斥的——要麼存在的是Skylight,要麼存在的是Reflection Capture,且在選擇時Relfection Capture的優先級高於Skylight。不光如此,移動端的Relfection Capture的範圍也無效。因為兩者的互斥關係移動端PBR渲染過程隻需要采樣一次cubemap,相比多次采樣cubemap更廉價,能耗更低。

但同時這些做法也帶來了一些問題:

1. 場景中同時存在Reflection Capture&Skylight時,因為Reflection Capture優先級高且範圍無效,永遠隻可能Reflection Capture有效。

2. 相對於非移動端來說,移動端的場景中IBL所提供的光照往往會來得更暗一些。

3. 因為Reflection Capture的範圍無效,物體在渲染時隻取離它最近的那一個,也導致在場景製作過程中,需要區分室內室外,樓上樓下,多變的環境氛圍時工作流幾乎不可能實現,因為無法精確控製範圍。這個問題對於想要製作高品質遊戲場景來說,說致命並不為過。

二、Reflection Capture 為何采集不到天空球

在場景和TA的強烈要求下,我們在移動端修複了Reflection Capture的作用範圍,想要在移動端讓範圍起作用,隻需要在FScene::FindClosestReflectionCapture裏查找和物體包圍盒相交的的Reflection Capture並處理好Mobilebasepass的ShaderBinding參數設定即可。

這個問題修複之後,TA很快又發現兩個新的問題:

1. 同樣的一樣IBL圖,當它作為Skylight輸入存在時比作為Reflection Capture輸入時對亮度的貢獻大很多。

2. 放在室外的Reflection Capture,上半部分是黑的,一查原來是采集不到Stationary的天空球。

第一個問題留到第三部分去說,第二個Reflection Capture采集不到天空球的問題,則是因為Skylight有一個選項用來控製天空球的Threshold。

1.jpg

這個選項的直接意思是:距離原點多遠之後的場景物體屬於天空球,這個默認值是1500米,即1500米以外的所有物體,都屬於天空。因為UE4在非移動端的實現中Skylight和Reflection Capture相互疊加,且當Reflection Capture和SkyLight同時可見時,優先選用的是Skylight的部分。這樣的話,在存在Skylight的室外,采集ReflectionCapture時確實不需要采集和存儲天空球。

這個設計初衷所帶來的問題在於:你要是移動端的話,你就完蛋了——你室外的光滑物體和純金屬,上半球一片黑。黑夜給了你的黑色眼睛,是你看到了自己心理的陰影?

我們來看看UE4在采集Reflection Capture時,是如何丟掉天空球信息的。

1. 實現代碼在ReflectionEnvironmentShader.usf 的CopySceneColorToCubeFaceColorPS函數中,代碼如下所示:

2.webp.jpg

這段代碼的解釋為:當當前采樣到的位置距離< 0.8 * threshold時,IBL的Alpha值為1,否則小於1,按1-Smoothstep曲線(似乎看到的實現,大多數SmoothStep都是三次曲線)方式趨向於0,當距離大於等於threshold時,Alpha必然為0,Alpha 值會被寫入Cubemap的Alpha通道。

2. SkyLightParametersValue參數傳遞的入口在ReflectionEnvironmentCapture.cpp中的FCopySceneColorToCubeFacePS類的SetParameters函數中,代碼如下:

3.jpg

可以看到這兒的SkyLightParametersValue.x即為 Skylight上的SkyDistance Threshold值。

3. 在FilterReflectionEnvironment函數中一開始執行一次premultiply alpha,這時alpha值同會乘以rgb值,所以會造成最終的cubemap中alpha為0的值也變成了全黑色,代碼如下:

4.jpg

即:Color = 0 * srcColor + destAlpha * destColor

經此一步之後,不管是移動端還是非移動端,其生成的Cubemap中被判為天空的部分已經全部為0,所以在反射球為移動端存儲編碼為RGBM時,早已沒有了這部分顏色信息……

三、移動端的IBL亮度計算

上文說到使用同一張Cubemap作為Skylight和Reflection Capture輸入時,得到的結果亮度不一致,於是乎TA提了一個BUG單。

沒過多久,場景美術發現無論是接受CSM實時陰影或是烘焙的ShadowMask,金屬物體上的陰影總是比非金屬上的陰影來得更黑一些,於是乎場景美術不光提了一個BUG單,還抱怨說UE4怎麼這麼多亂七八糟的問題,比隔壁另一個U字頭的引擎還不如?

Skylight和Reflection Capture亮度不一樣的問題,是因為Skylight的cubemap在渲染時直接使用的是cubemap的原始亮度,而Reflection Capture在渲染時亮度經過了縮放(大部分時候,這個縮放值都是小數,也就是說:它都會變暗)。具體的實現在MobileBasePassPixelShader.usf的GetImageBasedReflectionLighting函數中。

5.webp.jpg

可以看到在Reflection Capture的情況下,SpecularIBL會乘以縮放值。這個值是通過MobileComputeMixingWeight函數計算出來的——如果你用的UE4版本在4.23之前,那麼這個函數是不帶Mobile的ComputeMixingWeight,Mobile版本隻是簡單的把ComputeMixingWeight的所有數據類型,由float改為了half*,算法完全一致。

接下來我們詳細拆一拆MobileComputeMixingWeight的算法,先看看這函數的全貌(因為源代碼中的注釋有很強的誤導性,所以注釋去被我去掉了,同時我也簡化了一下代碼的布局)。

6.webp.jpg

算法分為這幾步:

1. 計算一個0~1之間的MIxingAlpha值。

7.jpg

這個值由ReflectionEnvironmentRoughnessMixingScaleBiasAndLargestWeight的x、y及當前像素的Roughness值來確定。Ref*Weight參數的計算過程。

8.webp.jpg

寫成數學公式:

x = 1.0/(b-a) ,b為結束Roughness值,a為開始Roughness值

y = - a / (b-a)

把上述x,y代入到MobileComputeMixingWeight中的MixingAlpha式中得

MixingAlpha

= smoothstep(0 ,1 , Roughness/(b-a) - a/(b-a)

= smoothstep(0 , 1 , (Roughness - a)/(b-a))

可以看到MixingAlpha值和Roughness值成正比,Roughness越大,則MixingAlpha值也越大,最大值不超過1(staturate所限)。

2. 計算MixingWeight(Normalized Cubemap)

9.jpg

這一個變量的命名和原始的注釋非常迷惑,按主流的說法,它該叫Normalized Cubemap,其作用是把當前IBL的間接漫反射亮度縮放到和從Lightmap或SH(ILC)中接收到的間接GI亮度一致。indirect_irradiance來源是物體當前像素的光照圖的亮度(靜態物體)或ILC的亮度(動態物體)。

算法簡化成公式如下:

normalized_scale = indirect_irradiance / ibl_average_brightness

一般的最終specular_IBL計算公式(UE4不完全一樣,見步驟3說明):

specular_IBL = sampled_cube * normalized_scale

其中ibl_average_brightness來源是當前經過卷積後的cubemap所計算出來的平均亮度,即roughness為1時所采的這張1*1的最小mipmap的亮度。

UE4中計算該IBL亮度時不是使用普通的亮度計算公式,而是使rgb的貢獻平均化。

ibl_average_brightness = dot(color.rgb ,float3(0.333,0.333,0.333)

UE4的亮度計算之所以使用均值,是因為如果使用標準的亮度計算公式,無法處理一些特殊的IBL邊界情形:當IBL中隻存在藍色時,亮度會非常小,而當IBL中隻存在綠色時,亮度又會非常大。但這麼做卻也並不是最優的選擇,我們將在第四部分進行說明。

3. 插值得到最終的縮放係數

10.jpg

注意到步驟1中結論:Roughness值越大,MixingAlpha越大,當Roughness大於等於結束Roughness時,縮放係數完全等於步驟2中計算出來的normalized_scale;當roughness小於等於開始Roughnes時,縮放係數等於1; 縮放係數其它情形下處於[1,normalized_scale]之間。

11.webp.jpg

由於在大部分情形下,normalized_scale小於1,所以也就可以看到一個現象:越光滑的物體,反射球對它的影響就越強,越粗糙的物體,反射球對它的亮度影響就越弱。

至於場景美術所提第二個問題——“金屬物體上的陰影總是比非金屬上的陰影來得更黑”,經查是TA做了一個很不PBR的材質規範:非金屬材質沒有AO通道,AO圖直接乘到了BaseColor上;金屬材質留有材質AO通道輸入了AO圖,BaseColor上不帶光照和遮擋信息。由於材質AO會同時作用於BaseColor和間接光照的亮度(indirect_irradiance *= AO),所以金屬物體的IBL縮放值會更小,從而更黑。

四、UE4移動端IBL的可用優化

1. 壓縮格式 :UE4移動端的Skylight cubemap是用的float原生的圖,既然定位等同於Reflection Capture,可以考慮使用RGBM的方式同樣的壓一壓?Reflection Capture的RGBM在Cook時也不接受ASTC/ETC/PVR方式的壓縮,要不要統一壓成硬件支持的格式?(UE4.26 Preview中,移動端已實現Reflection Capture的Cubemap壓縮,壓縮格式為ETC2)

2. Cubemap轉2D紋理:到ES3.1都不支持CubemapArray,故IBL的變化會導致動態Instance失效,是否可以一下把 Cubemap轉為經緯圖或橢球紋理,從而使用TextureArray+Custom PrimitiveData進行動態Instance合批的最大化,從而有效的降低Drawcall ?轉為2D紋理有2個小風險,經緯圖的紋理浪費比cubemap大概有30%左右,有同事在小米6/小米9實測,相對於Cubemap,經緯圖紋理采樣的CacheMiss也更高。

3.算法優化/效果優化:UE4的IBL Normalized算法使用的是標量的ibl_average_brightness和標量的indirect_irradiance來計算,這種方式計算所帶來的問題:

在未開啟Lightmap方向性的情況下,lightmap的亮度隻會計算上半圖的亮度,而ILC中的亮度可能來自於任意方向,這可能會給使用ILC和Lightmap的物體帶來不同的IBL亮度。

12.webp.jpg

由於ibl_average_brightness和indirect_irradiance兩部分的亮度計算公式不一致,normalized的效果可能會因間接GI的顏色而使IBL反射出來的亮度不一致。

由於ibl_average_brightness來源於cubemap全球麵的總和,而indirect_irradiance隻可能來源於當前像素法向上半球的輸入,故其亮度normalized的結果並不會使兩者的亮度相等,而可能會導致IBL未能表現出應有的亮度,同時也會降低IBL的方向性。

MobileComputeMixingWeight的MixingWeight計算代碼實現上未防止越界~~

COD黑色行動和戰神4中的IBL Normalize使用的是3階SH。

13.webp.jpg

本文來源:知乎專欄“圖形遊戲和宅”

文 | Jiff

华体会hth体育网 賞析
  • 2101期學員李思庭作品

    2101期學員李思庭作品

  • 2104期學員林雪茹作品

    2104期學員林雪茹作品

  • 2107期學員趙淩作品

    2107期學員趙淩作品

  • 2107期學員趙燃作品

    2107期學員趙燃作品

  • 2106期學員徐正浩作品

    2106期學員徐正浩作品

  • 2106期學員弓莉作品

    2106期學員弓莉作品

  • 2105期學員白羽新作品

    2105期學員白羽新作品

  • 2107期學員王佳蕊作品

    2107期學員王佳蕊作品

專業問題谘詢

你擔心的問題,火星幫你解答

微信掃碼入群領福利

掃碼領福利最新AI資訊

點擊谘詢
添加老師微信,馬上領取免費課程資源

1. 打開微信掃一掃,掃描左側二維碼

2. 添加老師微信,馬上領取免費課程資源

×

同學您好!

您已成功報名0元試學活動,老師會在第一時間與您取得聯係,請保持電話暢通!
確定