Friday, August 1, 2014

Light diffusing game

遊戲中的光線漫射

在攝影界
有些人會去買非常昂貴的攝影器材
但是拍出來的照片沒有任何美感
他只是喜歡把照片放大到100%
然後讚嘆這名牌鏡頭銳利的畫質
這樣他就滿足了

在音響界
有些人會去組裝非常昂貴的音響
但是對音樂沒有什麼品味
他只是喜歡聽那些「發燒片」雄渾立體的重低音
然後讚嘆音響器材美妙的聲音還原能力
這樣他就滿足了

至於在電子遊戲界
有些人會去組裝非常昂貴的PC
他只是喜歡把遊戲所有特效和解析度開到最高
然後在論壇貼圖讚嘆這遊戲畫面有多精美
這樣他就滿足了
噢......不對
這類玩家有越來越難滿足的趨勢......

最近實在看到太多論壇發言
批判遊戲為何沒有做到一些現有技術做不到的事情
讓我很想寫一篇關於3D光影運算的粗淺文章

大概是廣告宣傳都會把家用主機或顯卡描述得有多威能
影視中的CG特效又已達到無所不能的境界
導致玩家對遊戲畫面水準的期待和現實產生落差

事實上,遊戲中要實現完全的即時光影運算
還有很長很長一條路要走......


正題開始
上面這張圖片,展示了三個中空的方塊和一隻紙鶴
來自於後方的光源沒有產生投影
所有物件看起來都像飄在空中
沒有距離感


計算陰影之後好些了
但是看起來光影依然很平很不真實

在現實中,光線打到物體表面之後
會再反彈出去
不同的材料會有不同的反彈角度和強度
反彈出去的光線下一次接觸到物體表面之後會繼續反彈下去
這些漫射出來的光線填充了空間中各個角落
所以白天室內就算不開燈也沒有陽光直射
窗外還是會有漫射的光線進入,不會漆黑一片

下圖就讓軟體計算光線反彈漫射的狀況
這通常稱做Global Illumination,簡稱GI,也有人稱做Indirect Lighting


影像立刻活起來了
可以看到黃色的物體反彈出黃色,打在旁邊的白色物體上

黃色方塊雖然整個正面都是背光
但正面右側接收到白色方塊反彈的光線,所以比正面左側亮
這樣的陰影濃淡自然變化
不計算GI是無法得到的

這樣看來,計算光線漫射似乎很簡單
但事實上
上面這張只有單一光源、只有純色簡單材質的影像(尺寸只有960*540px)
花了超過5分鐘才計算出來
光線反彈的次數設定計算到反彈第五次
開了中高品質取樣,還是可以在陰影處看到雜訊
若是低品質,雜訊會慘不忍睹
(有些不同算法不會產生雜訊,但會有不規則光斑或物體邊緣溢光)

換句話說
這樣的光影計算方法
不可能在每秒幾十張的遊戲中,每格都算一次
若降低計算精確度,只會給畫面帶來反效果
對影視動畫產業而言
也不可能忍受光斑、雜訊、邊緣溢光等等低品質影像
高精確度計算的時間和硬體成本會非常驚人

所以過去業界常用另一種較簡便的擬真陰影產生方式
Ambient Occlusion,簡稱AO
它不去計算光線真正的反彈結果
它計算的是物體表面上每個點的「環境遮蔽率」

簡單來說,它假設地平面以上的天空,是個半球體的光源
像是一個大碗蓋在地上
光線從這個半球體大碗,均勻地往內部空間照
AO算的是,這個大碗中物件表面的每個位置上
會有多少比例的光線被周遭物體遮蓋掉

直接看圖或許比較好懂
單純只計算AO就是如下的影像


應該可以看出
AO只是單純計算出,每個位置上會有多少來自假想半球體的均勻光線被周遭物體檔到而變暗
完全不是燈光投影的概念
和第二張圖疊合在一起就會是以下結果


雖然遠不如GI計算出來的影像
但總比原本直接光投影要好多了

其實AO在影視動畫業最初的用法,應該是要分多道pass算圖

1.一張完全無光影只有物體原色的影像
2.疊上AO產生的暗部描繪出物體輪廓形狀
3.再補上場景中燈光投影的效果

第三個步驟疊合的光影,會把AO產生的部分陰影打亮
經過繁複的合成手續才會疊出自然的光影效果
但一般遊戲應用時
只單純把AO算出來的陰影疊在物體表面上
那會產生什麼錯誤呢?
上圖中最明顯的例子。請看黃色方塊左面底部有一條陰影
但那個位置是直接受光面,不該有陰影存在
對照一下GI計算的影像
就可以看出明顯的差異

不過說了這麼多,其實一直到今天的軟硬體水準
依然無法在遊戲中即時計算精確的AO
過去是把AO陰影直接「畫」在材質貼圖上
而目前遊戲中常見到的,都是SSAO

SSAO是在Crytek任職的Vladimir Kajalin想出來的天才方法
Crysis是第一個應用此技術的遊戲
它不對場景物體的進行計算
直接利用GPU算好的影像(z-buffer通道......這很難三言兩語解釋,請原諒我不解釋了)
在物件邊緣快速描出陰影


這是應用在Saints Row VI中的效果
不是很自然,但總比什麼都沒有好
SSAO經常在不該有陰影的位置描出陰影
有些遊戲會使用較複雜的SSAO算法
犧牲效能來換取比較好的影像
如下圖Far Cry 3 的例子


這是SSAO和HDAO的對照
角色身體邊緣距離後方物體很遠,不該描出陰影
SSAO在角色身體邊緣描出了一堆不該有的陰影
HDAO則呈現出較正確的結果

現在要再回頭談談GI
雖然無法在遊戲中即時運算GI
但是遊戲開發者可以預先算好一張固定的光線狀態存起來使用
這種手法叫做pre-baked GI (預先烘焙好的GI)
這份紀錄光線的資料通常叫做Lightmap
這種技巧在建築和室內設計的3D繪圖最常用
因為場景都是靜態的,本來就無須每格計算光線漫射
在遊戲中使用Lightmap搭配一兩盞即時投影的光源
就可以製造出很好的效果


上圖的例子來自Watch_Dogs
兩個圓圈內的區域同樣處於背光的陰暗面
卻有完全不同的亮度
就是因為GI計算出左邊圓圈處會接收到大量來自左方建築物的漫射光線

這種方法雖然不必即時計算光影資料,使用上仍然有限制
那就是它很耗記憶體
看門狗PC版系統要求最低6GB記憶體
有大半就是因為遊戲中的巨大城市場景必須使用非常大張的Lightmap
才能取得比較好的成果
因為新一代遊戲主機總算有8G記憶體可用
所以目前有兩款開放世界遊戲開始用pre-baked GI
一是Watch_Dogs,二是Infamous: Second Son
後者的城市尺寸比較小,可以使用更高解析度的Lightmap
所以效果也略好些

下圖來自使用Unreal Engine 3 的 Dishonored
畫面近處有一大叢燈光
緊靠著燈光的雕花柱腳,卻是一片陰影,非常不合理
這就是因為受限於記憶體,一般Lightmap能用的的解析度都必須壓得很低
無法提供較複雜的光影細節


這時候就該提到2011年現身,卻被罵到臭頭的id tech 5引擎
目前為止使用id tech 5 引擎的遊戲
只有Rage和Wolfenstein: The New Order

id tech 5 的獨家特色是MegaTexture
允許開發者把遊戲中所有材質融合成一張超大材質
最大尺寸可達128000*128000像素
如果難以理解那是什麼尺寸的話
就想像一下7900個full HD螢幕排起來的樣子
因為需要這麼多螢幕才能展示出如此龐大數量的像素

傳統遊戲引擎必須先將材質載入到記憶體中
所以記憶體大小直接限制了場景的尺寸和細節
但id tech 5 引擎不凡之處在於,它能夠串流處理它的超大材質
這讓開發者可以自由創造無限多的細節
不必受限於記憶體

然而......2011年Rage推出時
許多擁有高檔配備的玩家將它批評得體無完膚
說它只會靠貼圖太落伍、缺乏動態光影

眾玩家們批評的點實在有欠公允
因為即使到了2014年的今天
每一款頂級遊戲的畫面還是都得靠Lightmap的「貼圖」
不是真正即時運算的光影
不過Rage確實沒有完全發揮id tech 5 的實力
上個月發行的德軍總部就真正展現了「靠貼圖」可以做到什麼樣的程度


這是一個照明非常有趣的場景
燈光位在天花板眾多管線之上
完全靠Radiosity算法算出來的反彈漫射來打亮整個場景
牆邊的管線擁有準確精緻的陰影
如此複雜的燈光條件
換成Unreal Engine或CryEngine都無法做到此水準
靠著id tech 5 獨家的MegaTexture串流技術,突破傳統引擎的記憶體限制
玩家們終於能在遊戲中見到如此精緻的光線漫射
補上一張Crysis3類似場景的擷圖
牆上較小的物件都缺乏正確的陰影
立刻就能對照出光影細緻程度的差距


CryEngine3宣稱達成了即時運算的GI
事實上,它的LPV算法侷限非常多
只有單一光源(戶外日光)會反彈、只能反彈一次、物件必須對齊格點否則會被看到漏光
Crysis3絕大多數的場景還是都仰賴預先算好的靜態GI
搭配SSAO來製造假象

另外,Unreal Engine 4 曾經宣傳過他們的SVOGI
最後還是因為效能問題而放棄
只能依靠預先算好的GI+動態反射+動態高光,來盡量模擬出逼真的影像
UE4也提供CryEngine3那套侷限多多的LPV算法
但漏光的問題仍有待解決
精確程度也必定遠低於預先算好的GI

換句話說
想在遊戲中看到即時運算的GI,仍然不是短短幾年內可以實現的
不管是名氣響亮的Unreal Engine 4 、 CryEngine3、還是Frostbite3 都一樣
而當初被批得體無完膚的id tech 5
恐怕才是目前能夠打造出最細緻光影的遊戲繪圖引擎
寫本文另一個動機,大概就是為id tech 5 平反吧




No comments: