[GDC16]Global Illumination in Tom Clancys The Division
Global Illumination in Tom Clancy The Division
https://www.zhihu.com/video/951185121647280128GI 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的index3)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:遊戲引擎 |