標籤:

[GDC16]Global Illumination in Tom Clancys The Division

Global Illumination in Tom Clancy The Division

https://www.zhihu.com/video/951185121647280128

GI on/off的對比

曼哈頓場景6平方公里以上,193w物件,2w車輛,3w垃圾堆。大場景外加大量物體沒法很好地使用Lightmapping等GI,比較適合的就是probe based的方法,一般light probe/irradiance probe等,實際產品中美術不用再處理uv、改動一點就會rebake的煩惱。

有晝夜變換,ambient很重要,有些場景始終在shadow中,所以需要prt probe。

晚上使用點光、錐光、面光源。在之前farcry中secondary bounce baked進probe,但是在Division中這些光源全是dynamic/editable,所以需要更進一步。

很多室內環境,大量使用dynamic光源,而且對於有窗戶的室內依然受晝夜影響,這種情況很適合用probe,但是要小心注意probe的位置防止不同房間的bleeding

Dynamic weather,對於procedural snow一般GI會有點問題,但是prt只需要一些修改就可以使用

PRT可以看Sloan的論文,DX sample中也有

Brute force的方法,直接存所有的visible surface element,像GBuffer cubemap per

probe

從probe發射光線,交到的第一個物體保存為surfel信息

對於沒有交到物體的光線,認為是hit到了sky,結果作為spherical shadow term,相當於large scale directional ao

需要把normal方向的radiance積分為半球的irradiance(light probe->cosine),常見的方法轉為頻域,2階SH的缺點會丟失對稱的強光信息,好處GPU-friendly,只需要4float;HalfLife2使用6 basis,缺點是由於basis是固定的,所以fading會有瑕疵

最後選用了HL2的做法,bake6個basis irradiance,realtime blend

2種自動Probe擺放方式:1)每隔4m的grid,從上至下raycast,hit到的地方放置probe;2)沿牆放置,防止整面牆flat-looking

存放的數據:把probe分割到64*64的2D grid中,每個gird最多1000的probe(一般200-300),根據player的位置stream in/out

在同一個sector中的probe共用Surfels數據,這樣GPU的relight計算會少很多。Surfels使用2級的hash來索引

第一級cell平均surfel的position/normal/albedo等信息,使用position和normal作為hash index,cell的大小1*1*1m,如果設置cell太大會有光照的bleeding,太小計算量會增加

第二級average多個cell為一個irradiance brick,為了加速probe計算,所以讓probe直接索引brick而不用索引大量的surfels。4*4*4的brick

具體的data存放

1)probes保存position、sky visibility HL2 irradiance probe、以brick factor的range

2)brick factors保存當前brick給probe貢獻光照的權重、irradiance

brick array的index

3)bricks保存兩個index

4)surfels保存所有relight需要的信息

離線bake過程,對於同一個sector的probes

1) 渲染它的GBuffer cubemaps

2) CPU read back,把所有的surfels放到hash grid,得到average surfel和irradiance brick

3) 在同時,GPU渲染下一個sector

對於Manhattan的數據需要8小時bake,1GB肯定壓縮了吧

Real-time

不是使用不同時間段的probe進行插值,而是更精確的每幀更新

舉個例子,左圖是因為牆面的secondary bounce變紅,這種情況在一天之中就幾分鐘,離線bake很難插值出這種情況,除非densely bake。右圖是在陰影中,主要靠sky light和street bounce

簡單易懂,compute_lighting()跟普通的shading流程一樣

3個小時的差別,只看sun的irradiance差異很明顯

由於shadow的範圍限制,有些surfels在shadowmap的外圍,這樣計算的結果不正確。維護一張大的shadowmap又太費,折中的方案是記錄last shadow sample,因為sun dir的變化頻率不大,所以這樣也看不出太多問題

CPU先計算當前sector surfels AABB所交的所有lights,把他們的attrib放進GPU里計算。(這計算量,嘖嘖)其中優化是可以把靜態光源的結果cache到buffer中

效果真的挺好

Blend snow white albedo

這個想法也是吊,使用上一幀的probe來計算surfel的radiance

這不會越來越亮嗎。。。

根據當前sky的SH係數和預存的visibility SH計算sky irradiance

效果真不錯

做個brick的離散積分,over

這麼快?即使每幀只bake兩個sector也太快了吧,考慮這麼一堆的light computing

Merge irradiance到一張大的camera based volume map上,使用trilinear filter,每個basis自己計算offset uvw。Deferred/Forward管線都能用,所以opaque和translucent的物體都有GI

100*50*100m太大,對於室內使用一定會bleeding,所以室內單獨使用了interior volume,利用stencil做區分,對於每個房間,也會做AABB的volume clamp

對於遠處使用了irradiance的』LOD』,只計算sky的irradiance

差別挺大

AO的3個來源,對於車輛AO的效果不好,所以下面放一個decal

製作簡單

用一個單獨的volume存average irradiance,在裡面ray marching

最初的實現使用實時生成的irradiance volume,因為生成速度太慢所以會產生light poping,day-night切換等問題

PRT一開始使用8 basis,由於缺少+-Y所以顯得太暗,最後使用的HL2 basis

有些地方沒有probe,右圖可以看出建築中沒有擺放probe都是黑的,debug可以顯示沒有probe的區域用紅色標記。最好可以讓美術更自由的控制probe的擺放,另外,可以考慮使用tangent space中的xyz basis來代替6 basis給建築使用

室內外會有sharp transition,通過擺放能解決一部分,另外full shading中也不是太明顯

提升精度,另外對multiple bounces的粗略近似

UI的參數需要儘可能的簡單和易懂

Q&A中提議使用Cascaded grid,不錯的想法。sector的邊緣的lighting不正確,因為sector中surfel數據的不連續性。怎麼對比GroundTruth,作者說美術覺得OK就行。。。

這篇GI的成熟度和產品化做的相當好,也看出Ubi是一代一代積累帶來的效果突破,理論其實不是太難,主要是產品化時碰到的實際項目問題和細節問題,這類的坑是最難踩的。另外,除了lightmap,這個實現感覺和Enlighten比較像?不知道Enlighten具體怎麼做的(逃


推薦閱讀:

從零開始手敲次世代遊戲引擎(四十二)
[GDC17] Ghost Recon Wildlands:Terrain Tools and Technology
[翻譯]DOOM(2016) - Graphic Study
[CppCon14] How Ubisoft Montreal develops games formulticore – before and after C++11
[GDC16] Optimizing the Graphics Pipeline with Compute

TAG:遊戲引擎 |