KlayGE 4.0中Deferred Rendering的改进(四):GI的神话
轉載請注明出處為KlayGE游戲引擎
?
上一篇解決了透明物體的渲染問題;本文將挑戰另一個實時渲染的神話,實時全局光照(GI)。
實時全動態GI
目前direct lighting在游戲中日趨成熟,比較前衛的游戲引擎已經不滿足于diect lighting的效果了,逐漸開始嘗試indirect lighting。早期的方法有通過離線渲染light map來實現靜態場景、靜態光源的GI。接著出現了PRT,可以處理靜態場景、動態光源。CE3用了Light Propagation Volumes的方法,不需要預計算,可以產生動態場景、動態光源的diffuse GI。不過其速度和質量確實不敢恭維。難道就不能有全動態場景、全動態光源、diffuse和specular通吃的實時GI方法嗎?有!Multiresolution splatting for indirect illumination(MRSII)前來救駕。
在KlayGE 3.12中,團隊成員atyuwen就已經實現了MRSII。經過半年多的改進,這種GI方法已經融入了新的Deferred Rendering框架中,并且性能也得到了很大的提升。下面就讓我們來看看這種神奇的GI。
MRSII的渲染流程如下(感謝vanish整理了此流程圖):
首先,G-Buffer需要做mipmap,接著在每一層檢測深度和法線的間斷點,把那些間斷點在stencil buffer中標記出來,得到了這樣的stencil buffer:
和之前的stencil規則一樣,最高位是1表示忽略。所以灰色的pixel是可以忽略掉的,黑色的是需要計算光照的。可以看出黑色所占的面積并不大,絕大部分pixel都被略過了。
另外,還需要生成一個Reflective shadow map。和shadow map類似,RSM也是從光源視角渲染一遍場景。除了深度以外,RSM還需要保存normal和flux信息。把RSM采樣出一些點,比如256個,作為 虛擬點光源(VPL)。目前KlayGE里面用的是均勻采樣的方式,以后將改成importance sampling的方式提高VPL分布效率。
最后,每個VPL都可以根據BRDF生成一個light volume。用這些light volume去照亮G-Buffer的每一層。初始的light volume是個半球,在它的vertex階段會根據各方向反射的亮度拉出某些頂點,生成一個奇怪形狀的light volume。這個階段因為涉及到大量的填充和計算,非常耗時,但因為stencil test是打開的,絕大部分pixel都會被擋掉,真正參與計算的pixel數遠遠少于G-Buffer的總pixel數,GI因此得到明顯的加速。經過 測試,在目前的場景下,如果只用一層G-Buffer(也就是不用multiresolution),速度只有用三層的一半。如果大于三層,速度已經沒有 提高了。所以默認就選了三層G-Buffer。
在生成每一層的indirect lighting結果之后,還需要做一個特殊的插值upsampling,才能得到光滑的結果。這個插值在MRSII的原paper中有描述,這里就不累贅了。
如果只是用一般的最近點插值或者雙線插值,結果會有很多悲催的鋸齒:
最后,把indirect lighting加到direct lighting中,繼續做下一步的shading pass。最終結果如下:
比較只有direct lighting的結果,可以看到右邊和地面被照亮了:
用了MRSII后,對于512×512的RSM、256個VPL、三層G-Buffer的情況下,GI在GTX480上只需要1.09ms、在 9800GT上需要4.3ms。目前還有不少性能空間可以挖掘,我預計在同質量的情況下,最終能達到在GTX480上0.5ms、9800GT上 2.5ms的速度。
這套GI的框架不但可以做這樣的反射型indirect lighting,也可以做caustics這樣的高頻反光,也可以處理sub-surface scattering等材質效果。在KlayGE以后的版本中,MRSII將會得到持續的發展。
本篇詳細講解了實時GI的做法,下一篇是關于post process的改進。
總結
以上是生活随笔為你收集整理的KlayGE 4.0中Deferred Rendering的改进(四):GI的神话的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SkMaskFilter (SkBlur
- 下一篇: linux 双机直连设置