GTA V 圖形分析摘要
此文信息主要摘自 Adrian Courrèges 同學的 GTA V - Graphics Study 系列 (1, 2, 3),俺昨晚從筆記拷出來時,給 Adrian 同學發了一封郵件,請他允許我 reblog 一下。在得到 Adrian Courrèges 同學的同意后,俺就放上來了。
本文信息提煉后,去掉了絕大部分科普,如有不適,請配合原文的更多細節。
環境渲染
- 最外層的 cubemap 是每一幀實時生成的,目的是簡化后續真實反射的渲染。
- 這個 cubemap 是一張低精度的 128*128 紋理,每個面 30 左右 drawcall,都是地表天空等較大像素貢獻的多邊形
- 全部是靜態物體,所以車輛的外殼反射不了其他的車和角色
- 這個 cubemap 隨后被轉成了雙拋面圖 (Dual-Paraboloid Map),投影過程類似球面映射,這樣的話相關 PS 開銷就從 6 個面降到了 2 個面 (一上一下,各 128*128),由于攝像機一般在車頂斜后方45度,反射的絕大部分時間都只用訪問朝上的那個面,如果用 cubemap 就是 3~4 個面。整體來看,圖像質量上四個側面受影響最大,頂面和底面保留最多,由于攝像機看到的車頂通常反射頂面,所以效果損失很小
主渲染流程
-
GTA V 的主渲染流程輸出到 5 個 RT 并匯入最終的每個像素,透明物體后期另行處理。五個 RT 分別是 Diffuse/Normal/Specular/Irradiance/(Depth/Stencil),繪制這些主體像素大約花了 1900 drawcall。
- Diffuse RT 內保存了每個像素所屬物體的本身的平坦材質色,一個特例 (看車的引擎蓋可以發現) 是部分物體保存了方向光的結果,A 通道下面單獨談
- Normal RT 里保存了每個像素的法線信息,alpha 通道存了一些植被相關的遮罩信息
- Specular RT 內 RGB 通道分別保存了高光,光澤度和菲涅爾強度信息
- Irradiance RT 內在 R 和 G 通道保存了主次光源對每個像素的貢獻,B 通道存了自發光信息 (車燈,路燈,霓虹燈什么的) A 通道存了一些角色皮膚和植被的標記
-
Depth/Stencil 共用一個 RT,分開說
- 深度圖保存了每個實際繪制的像素到攝像機的距離,每個像素的實際 Z 值是以對數形式保存的,因為 float 越接近 0 越精確,使用對數 (或倒數) 能有效提高超遠距離物體的精度 (降低 Z-Fighting)
- Stencil 用來標記每個像素上各種不同物件產生的不同信息,便于后期做針對性處理,具體在不同的位段做過標記的像素有:玩家控制角色/玩家控制車輛/NPC/NPC車輛/植被/天空
-
整個渲染以“Front-to-Back”方式進行,這樣可以最大化 early-z 的效果。這樣的結果是越往后,單個 drawcall 上被拒掉的像素就越多,越省 PS 時間
-
主渲染流程完成 (也就是這些G-Buffer合并之后) 后如下圖 (無天空,水體及透明物體,但含所有的光照和陰影)
裁剪、 LOD 和 Alpha Stippling
-
(裁剪和LOD) GTA V 內判斷一個物體是否渲染,是否以較高的精度渲染,是以單個物件為單位,在一個 compute shader 里完成的
-
解釋一下前面的 Diffuse 的 A 通道做了啥事
這個看起來像棋盤格一樣的東西叫 alpha stippling,是用來規律性地有選擇地拒掉像素的技術。目的是更平滑的 LOD 切換。傳統 LOD 的不同級別之間切換的時候,會有 popping,而 stipple 之后普通物體看起來就會“發虛” (尤其是邊緣),這樣切換時 popping 會弱化很多
陰影 (CSM) 和其他雜項 (RM/SSAO/SSS)
- CSM 輸出到 4 個 1024*1024 單位,但顯存內是一張連續的 1024 * 4096 貼圖 (注:這個不錯,以前的實踐是根據攝像機距離使用不同尺寸的 shadow map,GTA V 的統一尺寸更合理,性能也更好)。
- 四張貼圖由四個不同參數的攝像機由近及遠分別生成,越近的地方提供越多的細節;這樣的問題是需要畫四遍,好在 fov 很小裁剪效率更高,最終算下來 CSM 費了 1000 個 drawcall,這里的 drawcall 很廉價 (因為輸入/運算/輸出量都很小)
- shadow map 也經過了與上面類似的抖動處理,這樣邊緣經過模糊后會更平滑
- 關于模糊有個小優化:先弄個 1/8 尺寸的貼圖做一個輕量級的 blur,以明確哪些地方無陰影/部分陰影/全陰影,然后做全深度的 blur 時就能忽略那些無陰影和全陰影的像素了,可以省掉大量的像素操作
- (Planar Reflection Map) 這玩意費了 600 drawcall 反著畫在一個 240*120 的紋理上,用于大面積水面的反射
- (SSAO) 半精度,做了一下深度相關的模糊
- (SSS) 嘴唇處的 3S 效果是很顯著的,對比上面兩張大圖。由于 Stencil Buffer 里一個位段專門存了玩家控制角色的像素貢獻,而 Specular Map 內的 a 通道存了皮膚的像素貢獻,通過這些信息可以做到在最少的像素上做 3S (對臉部專門處理性價比高一些,因為這是個看臉的世界-_-)
水面,霧效,大氣 (體積陰影)
- 用了兩張圖:Diffuse Map 里存了水的本色,Opacity Map 在 R 和 G 通道里分別存了水的透明度和那一像素的水深信息 (用于透明度貢獻率的計算) 存水深還有個好處是,順便把 z 值過了確定是否可見 (也就是說 G 通道決定了是否對最終效果有貢獻)
- 最后實際繪制用了先前提到的反射圖,折射圖和 Bump Map
- (light-shaft map) 用于把陽光無法直射的區域的亮度壓下去,半精度,順便 blur 了一下讓效果更自然
- 霧效的最重要的作用是掩蓋遠處低模的細節,數據來源以之前輸出的深度圖為主
- 天空 (半球,一個 drawcall) 和云 (環狀 mesh,見三國志9) 沒有用生成的 (反正硬盤不值錢哇哈哈哈)
透明物體和修修補補
- 墨鏡,擋風玻璃,大燈的燈罩
- 揚起的塵埃盡可能 instancing 了
- 這一幀所有透明物體共 11 個 drawcall
- 利用前面存下來的像素把前面提到的參與 Alpha Stippling 的像素融合一下
后處理, AA 和 Lens Distortion
- Tone Mapping 使用了 Filmic Tonemapping Operators (神海2)
- HDR 用了四分之一精度,亮度用一個獨立 compute shader 存到一個單像素紋理上
- 算曝光,然后把較強光濾一把,這時候一般只剩幾個離得近的車燈了
- 然后是先往小再往大的迭代,回到半精度,最后 bloom/gamma 一下
曝光控制很重要,幀與幀之間的 coherence 控制一下,注意, GTA V 的“從暗轉亮”比“從亮轉暗”要快 (符合真實人眼感受)
- AA 不說了
- Lens Distortion 一個簡單的 PS 稍微形變一下,讓最終成像更有鏡頭感
界面
左下角的 UI 小地圖是預生成的小塊 tile,道路和建筑全部是矢量化的,無級縮放不損精度而且省空間
統計 (drawcall: 4155, textures: 1113, render targets: 88)
這兒不說啥了吧,看上面三個數字,嗯。
話題 a : LOD
R星的 LOD 確實令人發指,即使在 PS3 那 256M 內存上也是幾百公里隨便跑,進了游戲就沒有 loading 這回事。高低精度的各種不同版本,滿足不同情況下順暢運行的需要。(當然這是游戲數據量大的原因之一)屏幕上目所能及的星星點點燈光大部分都是可找到出處的真實發光的光源。
每個方塊都用了同一張 32*32 貼圖(屏幕右下角),一共上萬個面吧,分批量按靜態/動態的更新頻率 batch 一下。運動著的車燈是動態更新的,晚上遠距離下只畫車燈就夠了,跑近了再切整模。
山體都有對應的低精度模型來做基礎的 diffuse 貢獻,這些低模可能是先自動生成再手動調整的。這些低模還可以用來生成一些次要的像素 (反射什么的)
這些以 GB 為量級的數據不斷隨著玩家的移動加載/釋放,大部分在內存里是壓縮狀態。
當視角從一個角色切到另一個(相距數公里)時,攝像機有一個拉遠再拉近的效果,用動畫來避免了瞬間的IO過載。正常開車的移動速度跟這個相比就慢多了,streaming 完全沒有問題。而飛行速度就快多了,相應地,由于視線很遠,大多細節可以去掉,或用低精度模型代替。
話題 b : 特效
游泳池和海面不同,游泳池只是動一下法線,海水動法線不夠,頂點也是實時更新的。反射貼圖的精度很低,因為各種特效一蓋就看不出來了。
鏡子是簡化的沒啥特效的水,反射質量也就是像素精度是可調的,距離超出范圍就會變成黑板。
這個 Anamorphic Lenses 只有迎面過來的強光才會有,跟普通 Lens 一樣生成的動態 sprite。
話題 c : 景深
用了 Circle of Confusion 做景深,存了 signed (-1, 1) 符號直接用來表示與焦點的關系。這個 CoC Map 用來與深度配合,獲取前景/背景的信息,相鄰像素的模糊關系及是否位于焦點上等信息。結果是前景的模糊融入焦點范圍 (這一塊用一張專門的圖分離出來做模糊),背景模糊與焦點分離。
其他的 Heat Haze, God Ray 啥的,不多說了。
最后,感謝 Adrian Courrèges 同學的精彩系列文章。
[完]
Gu Lu
[2015-12-30]
來自: http://gulu-dev.com/post/2015-12-30-gtav-graphics