基於胡謅的物理光照模型

前言

在實時渲染的領域裏,全部的東西都是胡謅的,只有相對胡謅和沒那麼胡謅的區別。PBR材質就是相對沒那麼胡謅的那個,當中仍是有大量的東西是很隨便的。程序員

材質參數

咱們都知道經典的Phong材質控制五個參數,除去Ambient以外,有:segmentfault

  • Diffuse Intensity函數

  • Diffuse Colororm

  • Specular Intensity遊戲

  • Specular Colorip

  • Specular Hardnessget

反正就是這五個自由量了,咱們把它轉換成另外的一些參數:博客

  • Albedo Color:反照顏色數學

  • Metalness:金屬性,或導電性it

  • Fresnel Color:菲涅耳顏色,即反射顏色

  • Roughness:粗糙度,即1 - Glossiness(光滑度)

略有差異,可是大都是對應的,除了Diffuse Intensity,由於從如今開始Diffuse Intensity是一個常量了,與材質無關的常量。

光照模型

$$
L = (f_{\text {Albedo}}(v, l, c_{\text {Albedo}}) + f_{\text {Specular}}(n, l, v, c_{\text {Fresnel}})) \otimes c_\text {Light} \cdot \pi (n \cdot l)
$$

咱們看這個公式整體上是一種(A+B)*C的感受。C是一切視覺的源頭 —— 光,因此它做爲整個式子的一個因子乘進去。$\pi (n \cdot l)$跟咱們之前用Phong模型的時候算diffuse部分的方式同樣:不難理解,越是斜的面越難以接收到光。$c_\text {Light}$是光的顏色,你能夠根據距離衰減即不少其它的因素,決定這個顏色,也沒必要侷限在0到1的範圍內,反正咱們有HDR。

剩下的A+B,就分別是Albedo項和Specular項了。跟Phong模型相比,而Specular仍然是完美的鏡面反射。可是Diffuse項不見了,變成了Albedo項。

不知你們還記不記得Diffuse的意義:表面均勻反射光源的方向到半球各個方向。而Albedo是這樣一個意義:不知道從哪裏來可是在通過若干(物體內部或者表面的)反射散射以後,總而言之,這表面上這一點射出的一堆雜亂的光線」。二者不一樣的是,Diffuse咱們知道光線是從哪裏射入的,也知道從哪裏射出。可是Albedo咱們不知道光線是從哪裏射入的,包括漫反射和次表面散射。這個很是難以估量。

「哦,很是難以估量對吧」。遊戲程序員聽完光學專家的報告後,一摔筆記本,「那咱們他媽就不算了」。今後在不少遊戲裏,就有:

$$
f_{\text {Albedo}}(v, l, c_{\text {Albedo}}) = \frac 1 \pi c_{\text {Albedo}}
$$

也就是說直接乘了一個係數平衡一下外面光照的那個$\pi$。對就是這麼任性。咱們能夠看到把這一項提到括號外面以後,是否是有一種Lambertian模型漫反射的感受,雖然它的意義是反照。這就是爲何我剛纔說漫反射係數變成了常數(1)。而不少地方在講這一項的時候,仍是把它說成是Diffuse或者Lambertian Model。可是要記住,這實際上是Albedo,只不過咱們在簡化它的時候不精確地簡化成了漫反射而已。

BRDF和微表面理論

講完了胡謅的Albedo,就是沒那麼胡謅的BRDF了。講數學、講物理,我是怎麼都不夠那些大神來的了。你們在讀這一節的時候,記得要跟龔敏敏的文章和Real Time Rendering一塊兒看。

BRDF(雙向反射分佈函數)是僅僅對錶面反射的度量,表面如下的散射狀況是不考慮的。它是一個描述「從某個方向射入的光線,從哪些方向上反射出去了呢?」的分佈,或者「從某個方向看到了一束光線,它多是由哪些方向射進來的光線的反射光組成的呢?」的分佈,這是它「雙向」的意義所在。分佈是Solid Angle空間上的,也就是弧度角的三維版,不過咱們大可不去關心它。

BRDF雖然度量全部的反射光線,可是沒有規律可循的反射,咱們剛纔放在Albedo裏一塊兒算了。因此如今算的就只有有規律可循的,也就是鏡面反射的。因此咱們引進了微表面模型來度量鏡面反射。總結來講,咱們對射出光線的三種分類:

* 次表面散射(SSS) 漫反射(Diffuse) 鏡面反射(Specular)
實時渲染 Albedo Albedo Microfacet
簡化模型 0 Albedo Microfacet
物理度量 BSSDF BRDF BRDF

微表面模型的核心是假設了物體由不少微小的__完美鏡面__組成,而且創造出「宏觀法線」和「微觀法線」的概念。所謂宏觀法線,就是在描述物體形狀時計算出來的法線,或者法線貼圖中採出來的法線。而微觀法線,是用來衡量物體微觀、微表面下的粗糙程度用的,它對材質的光學性質有很大影響,可是不描述物體的幾何性質。

兩個法線是有必定聯繫的,畢竟宏觀是由微觀組成的。微表面大多數仍是和宏觀表面同向,可是呈現必定的機率分佈。對於粗糙的表面來講,貌合神離,不少微表面朝向其它方向;對於光滑的表面來講,衆志成城,你們都向反射同一個方向的光。

微表面度量鏡面反射,拋棄全部沒法將光線反射到人眼中的微表面。沒有被拋棄的那些微表面,擁有Half Vector,它們是光源和人眼之間的完美鏡面。Half Vector是什麼?記不記得之前算Specular是怎麼算的,用視線和光線之和,跟法線求點積。對,如今你知道Half Vector是什麼了。

$$
h = \text{normalize}(v + l)
$$

Cook-Torrance Model

Cook-Torrance是在微表面理論上創建的模型,引入了Roughness這一個參數,做爲整個模型的核心,核心思想是度量擁有Half Vector的可見微表面數量。咱們先回顧一下剛纔談到的概念:

  • 只有擁有Half Vector的微表面能提供Specular高光

  • 微表面法線(就是微觀法線)整體跟宏觀表面一致,可是有必定的分佈

  • 微表面有可能不可見,稍微要調整一下

咱們爲了計算Specular高光,就是要計算表面上__可見的、擁有的Half Vector的微表面__。因此,咱們一個一個解決這些問題。

$$
f_\text{CookTorr}(n, v, l) = \frac{DGF}{4(n \cdot l)(v \cdot n)}
$$

分母是用來保持能量和一些經驗參數,不去深究。咱們來一個一個看看DFG分別解決的是什麼問題:

  • Distribution(n, h): 分佈項。解決的最基本的數量問題。

  • Geometry(l, v, h, n): 幾何項。解決的是可見的問題。

  • Fresnel(n, l, h): 菲涅耳反射項。解決的是顏色和反射強度的光學問題。

Distribution

單純按照一個表面的法線未必能把光源的光反射給你,可是它下面的一個微表面或許能夠。顯然,這樣的微表面的法線與宏觀表面越是接近,出現的機率就越大。這很容易用一個機率密度函數去表達。只要是圍繞一箇中心分佈,你喜歡的話能夠用正態分佈、學生氏分佈 —— 可是在圖形學裏咱們更喜歡Beckmann分佈,它更有物理背景。

$$
\alpha = \text{Roughness}^2 \\
D(n, h) = \frac{\alpha^2}{\pi((n \cdot h)^2 (\alpha^2 - 1) + 1)^2}
$$

Geometry

這個因子在考慮光線的射入和射出可能會被遮擋的問題。

$$
k = \frac {(\text{Roughness} + 1)^2}{8} \\
G_1(x, n) = \frac{n \cdot x}{(n \cdot x)(1 - k) + k} \\
G(l, v, h, n) = G_1(l, n)G_2(v, n)
$$

握草這一大堆什麼來的。不急不急咱們慢慢看一下。k就是遮擋率了,一個由粗糙度算出來的經驗參數。在遮擋率接近0的時候,G1也接近1,也就是幾乎全部的微表面都能被看到,固然,不多是0,由於算不出來(笑)。在遮擋率接近1的時候,G1接近nx,也就是越是垂直於表面的光線難以被遮擋,越是斜的光線越是被遮擋得多。

Fresnel

剛纔咱們一直都在算微表面的數量,而如今作的則是相似於之前算反射強度的那一步,而且把反射顏色引入進來。固然了,如今算的就不是什麼點積了,那不物理。物理的是Fresnel方程,它描述了反射光強度和反射角度的關係。

不知道你們之前學大學物理光學的時候,有沒有接觸過偏振光。一束天然光裏經常會有兩種偏振態的偏振光,兩種的電場方向相互垂直。電場方向與反射介質平面的夾角越是小的一方,就越容易被反射。之前作過相關練習題,到如今還有印象。你們也能夠試着回憶一下之前物理老師講過的偏振原理。

根據物理測量,Fresnel方程能夠經過Schlick等式去近似:

$$
F_{\text{Schlick}}(l, h) = c_\text{Fresnel} + (1 - c_\text{Fresnel})(1 - (l * h)^5)
$$

這裏倒沒有太多咱們非物理專業能夠折騰的事情了。

金屬和塑料

根據物理測量,導體的Albedo Color幾乎爲0,而Frenel Color各異且較高。而絕緣體的Albedo Color各異,但Fresnel Color略低(0.04),且均勻反射。遊戲程序員因而又動了歪腦筋:他們一直嫌GBuffer的空間太少了。

他們把兩個顏色合併成了一個顏色,稱爲Base Color(基調色),而後根據材質的導電程度,看看這個基調色到底是做爲反照色仍是反射色。又或者是半導體 —— 既組成反照色也組成反射色。

多光源和環境貼圖

光學原理很基礎的一條就是線性性:光的疊加就是線性疊加,不是混合,沒有前後。因此多光源的材質,只須要多遍渲染,而後用Plus Blend混合起來就能夠了。

在多光源達到一個極致的狀況下,就是處處都是光源。不少時候咱們用環境貼圖來描述這些極致多的光源,一般用來描述鏡面反射的結果。由於以前咱們曾經有一個Distribution項目,它讓光不只僅做用在正對着光源的方向,還成機率地做用在周圍。也就是一個擴散。

不知道說到Distribution你們想到什麼。我想到了高斯分佈、高斯卷積核、高斯濾波。我一年多之前曾經發過一篇博客[1],講的是卷積,但願你們還記得那隻模糊的Saber。當每一點都產生了一個形狀的擴散的時候,事實上就是一個卷積或者一個濾波。結果就是模糊。

在實時渲染時,咱們經常會把紋理預先濾好波,而後放在不一樣Level的Mipmap上。而後在畫的時候,只要替換掉剛纔的Fresnel Color,就能夠作出不一樣粗糙程度的環境貼圖了。

參考資料

對,可是本文沒有插圖,由於我太懶了。

相關文章
相關標籤/搜索