1. 程式人生 > >第五章 Unity中的基礎光照(1)

第五章 Unity中的基礎光照(1)

上進 如何 而後 比較 復雜 體積 img 哪裏 distrib

目錄

  • 1. 我們是如何看到這個世界的
    • 1.1 光源
    • 1.2 吸收和散射
    • 1.3 著色
    • 1.4 BRDF光照模型
  • 2. 標準光照模型
    • 2.1 環境光
    • 2.2 自發光
    • 2.3 漫反射
    • 2.4 高光反射
    • 2.5 逐像素還是逐頂點
  • 3. 總結

渲染總是圍繞著一個基礎問題:我們如何決定一個像素的顏色?從宏觀上來說,渲染包括了兩大部分:決定一個像素的可見性,決定這個像素上的光照計算。而光照模型用於決定在一個像素上進行怎樣的光照計算。

1. 我們是如何看到這個世界的

我們可能常會問類似這樣的問題:這個物體是什麽顏色的?如果讀者對小學自然課還有印象的話,可能還會記得這個問題是沒有任何意義的:當我們在描述這個物體是紅色時,實際上是因為這個物體會反射更多的紅光波長,而吸收了其他波長。而如果一個物體在我們看來是黑色的,實際上是因為它吸收了絕大部分的波長。這種物理現象就是本節要討論的內容。
通常來講,我們要模擬真實的光照環境來生成一張圖像,需要考慮3種物理現象。
(1)首先,光從光源(light source)中被發射出來
(2)然後,光線和場景中的一些物體相交:一些光線被物體吸收了,而另一些光線被散射到其它方向
(3)最後攝像機吸收了一些光,產生了一張圖像

下面,我們將對每個部分做更加詳細的講解。

1.1 光源

光不是從石頭裏蹦出來的,而是由光源發射出來的。在實時渲染中,我們通常把光源當成一個沒有體積的點,用l來表示它的方向。那麽我們如何測一個光源發出了多少光呢?也就是說,我們如何量化光呢?在光學裏,我們使用輻照度(irradiance)來量化光。對於平行光來說,它的輻照度可通過計算在垂直於l的單位面積上單位時間內穿過的能量來得到。在計算光照模型時,我們需要知道一個物體表面的輻照度,而物體表面往往是和l不垂直的,那麽如何計算這樣的表面輻照度呢?我們可以使用光源方向l和表面法線n之間的夾角余弦值來得到。需要註意的是,這裏默認方向矢量的模都為1,下圖顯示了使用余弦來計算的原因。

技術分享圖片
因為輻照度是和照射到物體表面時光線之間的距離d/cosθ成反比的,因此輻照度就和cosθ成正比。cosθ可以使用光源方向l和表面法線n的點積來得到。這就是使用點積來計算輻照度的由來。

1.2 吸收和散射

光線由光源發射出來後,就會與一些物體相交。通常相交的結果有兩個:散射(scattering)和吸收(absorption)。
散射只能改變光線的方向,但不改變光線的密度和顏色。而吸收只改變光線的密度和顏色,但不改變光線方向。光線在物體表面經過散射後,有兩種方向:一種將會散射到物體內部,這種現象被稱為折射(refraction)或透射(transmission);另一種被散射到外部,這種現象被稱為反射(reflection)。對於不透明物體,折射進入物體內部的光線還會與內部的顆粒進行相交,其中一些光線最後會重新發射出物體表面,而另一些則被物體吸收。那些從物體表面重新發射出的光線將具有和入射光線不同的方向分布和顏色。下圖給出了這樣的一個例子:
技術分享圖片
為了區分這兩種不同的散射方向,我們在光照模型中使用了不同的部分來計算它們:高光反射(specular)部分表示物體的表面是如何反射光線的,而漫反射(diffuse)部分則表示有多少光線會被折射、吸收和散射出表面。根據入射光線的數量和方向,我們可以計算出射光線和方向,我們通常使用出射度(exitance)來描述它輻照度和出射度之間是滿足線性關系的,而它們之間的比值就是材質的漫反射和高光反射屬性。
在本章中,我們假設漫反射部分是沒有方向性的,也就是說光線在所有方向上都是平均分布的。同時我們也只考慮一個特定方向上的高光反射。

1.3 著色

著色(shading)指的是,根據材質屬性(如漫反射屬性等)、光源信息(如光源方向、輻照度等),使用一個等式去計算沿某個觀察方向的出射度過程。我們也把這個等式稱為光照模型(Lighting Model)。不同的光照模型有著不同的目的。例如,一些用於描述粗超的物理表面,一些用於描述金屬表面等。

1.4 BRDF光照模型

我們已經了解了光線和物體表面相交時會發生哪些現象。現已知光源位置和方向、視角方向時,我們就需要知道一個表面是如何和光照進行交互的。例如,當光線從某個方向照射到一個表面時,有多少光線被反射?反射方向有哪些?而BRDF(Bidirectional Reflectance Distribution Function)就是用來回答這些問題的。當給定模型表面一個點時,BRDF包含了對該點外觀的完整描述。在圖形學中,BRDF大多使用一個數學公式來表示,並且提供了一些參數來調整材質屬性。通俗來講,當給定入射光線的方向和輻照度後,BRDF可以給出在某個出射方向上的光照能量分布。本章涉及的BRDF都是對真實場景進行理想化和簡化後的模型,也就是說,它們並不能真實地反映物體和光線之間的交互,這些光照模型被稱為是經驗模型。盡管如此,這些經驗模型仍然在實時渲染領域被應用了多年。
計算機圖形學的第一定律:如果它看起來是對的,那麽它就是對的。

2. 標準光照模型

雖然光照模型有很多種類,但在早期的遊戲引擎中往往只使用了一個光照模型,這個模型被稱為標準光照模型。實際上,在BRDF理論被提出之前,標準光照模型就已經被廣泛使用了。
在1975年,著名學者裴祥風(Bui Tuong Phong)提出了標準光照模型背後的基本理念。標準光照模型只關心直接光照(direct light),也就是那些直接從光源發射出來照射到物體表面後,經過物體表面的一次反射直接進入攝像機的光線。
它的基本方法是,把進入到攝像機的光線分為4個部分,每個部分都使用一種方法來計算它的貢獻度。這4個部分是:
(1)自發光(emissive)部分,本書使用Cemissive來表示。這個部分用於描述當給定一個方向時,一個表面本身會向該方向發射多少輻射量。需要註意的是,如果沒有使用全局光照(global illumination)技術,這些自發光的表面並不會真的照亮周圍的物體,而是它本身看起來更亮了而已。
(2)高光反射(specular)部分,本書使用Cspecular來表示。這個部分用於描述當光線從光源照射到模型表面時,該表面會在完全鏡面反射方向散射多少輻射量。
(3)漫反射(diffuse)部分,本書使用Cdiffuse來表示。這個部分用於描述,當光線從光源照射到模型表面時,該表面會向每個方向散射多少輻射量
(4)環境光(ambient)部分,本書使用Cambient來表示。它用於描述其他所有的間接光照。

2.1 環境光

雖然標準光照模型的重點在於描述直接光照,但在真實世界中,物體也可以被間接光照(indirect light)所照亮。間接光照指的是,光線通常會在多個物體之間反射,最後進入攝像機,也就是說,在光線進入攝像機之前,經過了不止一次的物體反射。例如在紅地毯上放置一個淺灰色沙發,那麽沙發底部也會有紅色,這些紅色是由紅地毯反射了一部分光線,再反彈到沙發上的。
在標準光照模型中,我們使用了一種被稱為環境光的部分來近似模擬間接光照。環境光的計算非常簡單,它通常是一個全局變量,即場景中的所有物體都是用了這個環境光。下面的等式給出了計算環境光的部分:
技術分享圖片

2.2 自發光

光線也可以由光源發射進入攝像機,而不需要經過任何物體的反射。標準光照模型使用自發光來計算這個部分的貢獻度。它的計算也很簡單,就是使用了該材質的自發光顏色:
技術分享圖片
通常在實時渲染中,自發光的表面往往不會照亮周圍的表面,也就是說這個物體並不會被當成一個光源。Unity5引入的全新的全局光照系統則可以模擬這類自發光物體對周圍物體的影響。

2.3 漫反射

漫反射光照是用於對那些被物體表面隨機散射到各個方向的輻射度進行建模的。在漫反射中,視角的位置是不重要的,因為反射是完全隨機的,因此可以認為在任何反射方向上的分布都是一樣的。但是入射光線的角度很重要。
漫反射光照符合蘭伯特定律(Lambert’s law):反射光線的強度與表面法線和光源方向之間夾角的余弦值成正比。因此,漫反射部分的計算如下:
技術分享圖片
其中n是指表面法線,I是指向光源的單位矢量,mdiffuse是材質的漫反射顏色,clight是光源顏色。需要註意的是,我們需要防止法線和光源方向點乘的結果為負值,為此,我們使用取最大值的函數來將其截取到0,這可以防止物體被後面的光源照亮。

2.4 高光反射

這裏的高光反射是一種經驗模型,也就是說,它並不完全符合真實世界中的高光反射現象。它可以用於計算那些沿著完全鏡面反射方向被反射的光線,這可以讓物體看起來是有光澤的,例如金屬材質。
計算高光反射需要知道的信息比較多,如表面法線、視角方向、光源方向、反射方向等。在本節中,我們假設這些矢量都是單位矢量。下圖給出了這些單位矢量:
技術分享圖片
在這四個矢量中,我們實際上只需要知道其中3個即可,而第四個矢量——反射方向可以通過其他信息計算得到:
技術分享圖片
這樣我們就可以用Phong模型來計算高光反射的部分:
技術分享圖片
其中mgloss是材質的光澤度(gloss),也被稱為反光度(shininess)。它用於控制高光區域的“亮點”有多寬,mgloss越大,亮點就越小。mspecular是材質的高光反射顏色,它用於控制該材質對於高光反射的強度和顏色,Clight則是光源的顏色和強度。同樣這裏也需要防止v·r為負數。
和上述的Phong模型相比,Blinn提出了一個簡單的修改方法來得到類似的效果。它的基本思想是,避免計算反射反向的r。為此,Blinn模型引入了一個新的矢量h,它是通過對v和l取平均後在歸一化得到的。即
技術分享圖片
然後,使用n和h之間的夾角進行計算,而非v和r之間的夾角,如下圖所示:
技術分享圖片
總結一下,Blinn模型的公式如下:
技術分享圖片
在硬件實現時,如果攝像機和光源距離模型足夠遠的話,Blinn模型就會快於Phong模型,這是因為此時可以認為v和l都是定值,因此h將是一個常量,但是,當v或者l不是定值時,Phong模型可能反而更快一些。需要註意的是,這兩種模型都是經驗模型,也就是說,我們不應該認為Blinn模型是對“正確的”Phong模型的近似。實際上,一些情況下,Blinn模型更符合實驗結果。

2.5 逐像素還是逐頂點

上面,我們給出了基本光照模型使用的數學公式,那麽我們在哪裏計算這些光照模型呢?通常來講,我們有兩種選擇:在片元著色器中進行計算,也被稱為逐像素光照(per-pixel lighting);在頂點著色器中進行計算,也被稱為逐頂點光照(per-vertex lighting)。
在逐像素光照中,我們會以每個像素為基礎,得到它的法線(可以是對頂點法線插值得到的,也可以是從法線紋理中采樣得到的)然後進行光照模型計算。這種在面片之間對頂點法線進行插值的技術被稱為Phong著色(Phong Shading),也被稱為Phong插值或法線插值著色技術。這不同於我們之前講到的Phong光照模型。
與之對應的是逐頂點光照,也被稱為高洛德著色(Gouraud shading)。在逐頂點光照中,我們在每個頂點上計算光照,然後會在渲染圖元內部進行線性插值,最後輸出成像素顏色。由於頂點數目遠遠小於像素數目,因此逐頂點光照的計算量往往要小於逐像素光照。但是,由於逐頂點光照依賴於線性插值來得到像素光照,因此,當光照模型中有非線性的計算(例如計算高光反射時)時,逐頂點光照就會出現問題。在後面的情況中我們將會看到這種情況。而且,由於逐頂點光照會在渲染圖元內部對頂點顏色進行插值,這會導致渲染圖源內部的顏色總是暗於頂點處的最高顏色值,這在某些情況下會產生明顯的棱角現象。

3. 總結

雖然標準光照模型僅僅是一個經驗模型,也就是說,它並不完全符合真實世界中的光照現象。但由於它的易用性、計算速度和得到的效果都比較好,因此讓被廣泛使用。而也是由於它的廣泛使用性,這種標準光照模型有很多不同的叫法。例如,一些資料中稱它為Phong光照模型,因為裴祥風(Bui Tuong Phong)首先提出了使用漫反射和高光反射的和來對反射光照進行建模的基本思想,並且提出了基於經驗的計算高光反射的方法(用於計算漫反射光照的蘭伯特模型在那時已經被提出了)。而後,由於Blinn的方法簡化了計算而且在某些情況下計算更快,我們把這種模型稱為Blinn-Phong光照模型。
但這種模型有很多局限性。首先,有很多重要的物理現象多無法用Blinn-Phong模型表現出來,例如菲涅爾反射(Fresnel reflection)。齊次,Blinn-Phong模型時各項同性的(isotropic)的。也就是說,當我們固定視角和光源方向旋轉這個表面時,反射不會發生任何改變。但有些表面是具有各向異性(anisotropic)反射性質的,例如拉絲金屬、毛發等。在後面我們將學習基於物理的光照模型,這些光照模型更加復雜,同時也可以更加真實的反映光和物體的交互。

第五章 Unity中的基礎光照(1)