实例比较虚幻引擎4与光线追踪渲染
下面兩幅圖,同樣的場景素材,同樣的光源,非常接近的材質模型,但用的是完全不同的渲染方法。
?
第一幅是我自己的渲染器用基于光線追蹤的無偏全局光照算法渲染,第二幅是用虛幻引擎(版本4.7)的渲染引擎渲染。
首先說明一下,第一幅圖片中椅子的扶手和桌子底部是塑料材質(漫反射加光滑鏡面反射),而第二幅中是金屬材質(粗糙鏡面反射)。原因是UE4導出的時候沒有把整個素材弄成一個材質了,我也懶得再編輯。然后桌上的雕塑第一幅是毛玻璃,第二幅是平滑玻璃。其余材質都一樣了。
接下來點評一下兩幅圖中的不同之處。第一個最抓眼球的區別就是場景底部平面的鏡面反射,兩個都是用粗糙參數為0.25^2的GGX模型 描述的粗糙鏡面,上下圖的差異很大。上圖是完全基于對BRDF和光源采樣的無偏結果,可當做參考,下圖則是可以說暴露了虛幻引擎4對輕微的粗糙反射的一個缺陷。虛幻引擎4中的反射解決方案是屏幕空間反射(Screen Space Reflection,SSR)加環境貼圖。對于非常平滑的表面,當它在場景中的反射剛好在屏幕上存在時,虛幻引擎4會使用SSR。當表面變的粗糙,或者反射部分在屏幕邊緣時候,反射會變成SSR和環境貼圖的加權和,直到對特別粗糙的表面完全變成使用環境貼圖。(其實這里我只要再把粗糙度調高一點,SSR就完全沒有了,不過那樣就完全看不出反射了因為環境貼圖的反射特別粗糙,不利于比較)所以下圖中的結果可以說是一個平滑鏡面反射和粗糙鏡面反射的加權和,當然無法真正模擬出輕微的粗糙反射。(這個問題用最近的Stochastic Screen-Space Reflections可以得到一定的解決,不過很多時候不那么robust)
第二個比較細微的區別則是下圖中桌椅黃色部分的鏡面反射有信息丟失了。這個便是因為SSR算法本身無法處理反射物體在不在當前屏幕上的情況。這個Artifact其實在現在的游戲中也非常常見,相信很多人都注意到了。SSR另一個細微的錯誤則是反射中的鏡面高光會是錯誤的,因為高光的計算取決于視線入射方向,域名購買直接從根據相機方向計算的屏幕上取是不對的。不過這個問題比前一個丟失信息的問題小多了,沒人care。。
第三個差別是底部平面的高光區域在下圖比上圖分散很多,看起來下圖底部的屏幕比上圖更加粗糙。這個是由于兩種完全不一樣的Image Based Lighting的方法導致的。上圖還是一切基于環境貼圖的能量分布采樣光源,虛幻引擎4則使用了Split-Sum,將渲染方程的光照部分和BRDF部分拆開分別積分,再對于兩個積分的結果球積。
其中光照部分的積分又使用了Prefilter Cube Map的方法。再講細一些,UE4的環境貼圖是128x128x6的分辨率,7層MipMap。每一層的每一面都用1024個樣本采樣不同粗糙度的GGX去Filter。這里有幾個產生誤差的原因,第一是誤差是采樣GGX的入射光線永遠是等于表面的法線方向,所以沒辦法模擬出上圖那樣在入射角和法線角夾角大的時候那種拉長的高光。另一個誤差則是只采樣了7個離散的粗糙度,并且不同的粗糙度使用的不同Mipmap,這樣做對性能更有利,但是這種粗糙度和Mip層的映射完全是Epic的人“發明”出來的,完全不是基于物理。我自己試過同樣的BRDF在UE4中做Image Based Lighting都會比真正的離線參考看起來粗糙許多。當然只要結果 Artists用著舒服,粗糙度看著有變化,也沒有什么不好的。
第四個差別是下圖中桌子下面的部分和上圖比明顯偏亮。這個誤差則是因為環境貼圖的遮擋信息只有在capture的那一點才是正確的,例如這里環境貼圖是在桌子上面capture的,桌子下面的部分大部分入射光被桌子遮擋,應該會比較暗,這里則變成桌子下面接收到的光照和桌子上面一樣,所以和上圖比偏亮了。解決辦法就是應該在桌子下面人工多capture一個單獨的環境貼圖。
除了這些區別,色調的不同,以及背景模糊度的不同,都是不同渲染系統的post processing參數以及其他工程性的小問題,就不細說了。
除了這些渲染本身的區別,實時渲染系統往往也需要更多的artists work才能hack出接近真實的畫面,例如在場景不同的地方放置probes,提前烘焙光照貼圖等。
最后,現在別說是用UE4做建筑可視化,就連做低成本動畫電影的都有。畢竟快速的迭代可以降低很多的成本,也就有可能出現一些非Pixar那種一定要男女老少都能看才能保票房的題材的片子。
而且要不是我這樣把UE4脫光了衣服拿出來比較,大家直接看著也不會覺得有任何問題。甚至我相信很多讀這個答案的人盯著這兩張圖看不出差別的。搞圖形的就是這樣。。廢了半天勁很可能是自娛自樂,真的搞的真實好看了,看得人也認為是理所當然。
總結
以上是生活随笔為你收集整理的实例比较虚幻引擎4与光线追踪渲染的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈程序的核心--复杂度
- 下一篇: 游戏开发者需要注意的4个内存使用问题