pbr_Theory

原文url:https://learnopengl.com/PBR/Theory

只寫了一部分,看不太懂

理論

PBR,也就是通常所說的基於物理的渲染,是一組渲染技術,它們或多或少地基於與物理世界更接近的底層理論。由於基於物理的渲染旨在以一種物理上合理的方式模擬光線,因此它通常看起來比我們原來的照明算法(如Phong和Blinn-Phong)更真實。它不僅看起來更好,因爲它非常接近真實的物理,我們(尤其是藝術家)可以根據物理參數創作表面材料,而不必訴諸廉價的技巧和調整來讓燈光看起來正確。基於物理參數的創作材料的一個更大的優點是,不管燈光條件如何,這些材料看起來都是正確的;這在非pbr管道中是不正確的。

基於物理的渲染仍然是對現實的一種近似(基於物理原理),這就是爲什麼它不被稱爲物理着色,而是基於物理的着色。對於一個基於物理的PBR照明模型,它必須滿足以下3個條件:

  1. 基於微平面模型。
  2. 能量守恆(不知道翻譯準確不,原文Be energy conserving)。
  3. 使用基於物理的BRDF。

在這個PBR教程系列指南中,我們將專注於最初由迪斯尼探索並被Epic Games用於實時顯示的PBR方法。他們基於金屬工作流程的方法得到了很好的文檔記錄,在大多數流行的引擎上都得到了廣泛的採用,並且在視覺上看起來非常棒。在本系列的最後,我們會得到這樣的東西:
在這裏插入圖片描述

請記住,本系列教程中的主題相當高級,因此建議您對OpenGL和着色器照明有很好的理解。本系列教程需要的一些更高級的知識包括:framebuffer、cubemaps、gamma校正、HDR和法線映射。我們也會深入研究一些高等數學,但我會盡我所能把概念解釋得儘可能清楚。

微平面模型

所有的PBR技術都是基於微觀層面的理論。該理論認爲,任何微觀尺度的表面都可以用微小的完美反射鏡來描述。根據一個表面的粗糙度,這些微平面的排列可以有很大的不同:
在這裏插入圖片描述

表面越粗糙,每個微面沿表面的排列就越混亂。這些微小的鏡面對準的效果是,當具體討論鏡面照明/反射時,入射光線更可能在粗糙的表面上沿着完全不同的方向散射,從而產生更廣泛的鏡面反射。相反,在光滑的表面上,光線更有可能以大致相同的方向反射,使我們得到更小、更清晰的反射:
在這裏插入圖片描述
在微觀層面上,沒有一個表面是完全光滑的,但是考慮到這些微刻面足夠小,我們無法在逐像素的基礎上對它們進行區分,所以我們根據給定的粗糙度參數對表面的微刻面粗糙度進行統計近似。根據一個表面的粗糙度,我們可以計算出與某個向量h大致對齊的微平面的比例。該向量h是位於光l和視圖v向量之間的中間向量。 我們之前在高級照明教程中討論了中間矢量,該矢量的計算方式爲l和v之和除以其長度:
在這裏插入圖片描述
微觀面與中間矢量對齊的越多,鏡面反射越清晰和越強。 加上粗糙度參數(介於0和1之間),我們可以從統計角度估算微面的對齊方式:

在這裏插入圖片描述

我們可以看到,較高的粗糙度值顯示出更大的鏡面反射形狀,而光滑表面的鏡面反射形狀更小且更銳利。

能量守恆 Energy conservation

微面近似採用了一種能量守恆的形式:發出的光能不應該超過入射的光能(不包括髮射表面)。在上面的圖像中,我們可以看到鏡面反射區域增加了,但是隨着粗糙度的增加,它的亮度也降低了。如果高光強度在每個像素上是相同的,而不考慮高光形狀的大小,粗糙的表面會釋放出更多的能量,這違反了能量守恆原理。這就是爲什麼我們看到鏡面反射在光滑的表面上更強烈,而在粗糙的表面上更模糊。

爲了使能量守恆成立,我們需要明確區分漫射光和反射光。當光線照射到表面時,它分爲折射部分和反射部分。反射部分是直接被反射而不進入表面的光;這就是我們所說的鏡面照明。折射部分是進入表面並被吸收的剩餘光;這就是我們所說的漫射照明。

這裏有一些細微的差別,因爲折射的光不會立即被表面吸收。從物理學上,我們知道光可以有效地被認爲是一束能量,它一直向前運動,直到它失去所有的能量;光束失去能量的方式是通過碰撞。每一種物質都由微小的粒子組成,這些粒子可以與光線發生碰撞,如下圖所示。粒子在每次碰撞時吸收部分或全部的光能,並將其轉化爲熱能。

在這裏插入圖片描述

一般來說,並不是所有的能量都被吸收了,光會繼續以(大部分)隨機的方向散射,與其他粒子碰撞,直到能量耗盡或再次離開表面。從表面重新發出的光線有助於表面的觀察(漫射)顏色。 但是,在基於物理的渲染中,我們做一個簡化的假設,即所有折射光在很小的撞擊區域就被吸收和散射,而忽略了會遠距離離開表面的散射光線的影響。 考慮到這一點的特定着色器技術稱爲次表面散射技術,該技術可以顯着提高諸如皮膚,大理石或蠟之類的材料的視覺質量,但以性能爲代價。

反射和折射的另一個微妙之處是金屬表面。金屬表面對光的反應不同於非金屬表面(也稱爲介質)。金屬表面遵循同樣的反射和折射原理,但所有折射的光都直接被吸收而不散射,只留下反射光或鏡面光;金屬表面無漫反射。由於金屬和電介質之間的明顯區別,它們在PBR管道中都得到了不同的處理,我們將在本文的後續部分對此進行深入研究。

反射光和折射光之間的區別給我們帶來了另一個關於能量守恆的觀察:它們是相互排斥的。任何被反射的光能將不再被材料本身吸收。因此,作爲折射光進入表面的能量是我們考慮反射後直接產生的能量。

我們通過首先計算鏡面反射率來保持這種能量守恆關係,鏡面反射率等於入射光線反射其能量的百分比。 然後直接從鏡面反射率中計算出折射光的分數爲:

float kS = calculateSpecularComponent(...); // reflection/specular fraction
float kD = 1.0 - kS;                        // refraction/diffuse  fraction

通過這種方法,我們既知道入射光的反射量,也知道入射光的折射量,同時遵守能量守恆原理。如果採用這種方法,折射/漫射和反射/鏡面的貢獻都不可能超過1.0,從而確保它們的總能量永遠不會超過入射光的能量;這是我們在之前的燈光教程中沒有考慮到的。

反射方程

這將我們帶到了稱爲渲染方程式的過程中,這個方程式是一個非常複雜的方程式,一些非常聰明的人提出來了,這是目前我們模擬光的視覺效果的最佳模型。 基於物理的渲染強烈遵循稱爲反射率方程的渲染方程的更專業版本。 爲了正確理解PBR,首先必須對反射率方程式有一個紮實的瞭解:

在這裏插入圖片描述

首先,反射率方程似乎令人生畏,但隨着我們對其進行慢慢剖析,您會發現它逐漸變得有意義。 爲了理解方程式,我們必須深入研究放射線學。 輻射度是電磁輻射(包括可見光)的測量。 我們可以使用幾個輻射量來測量表面和方向上的光,但是我們僅討論與反射率方程(稱爲輻射率)相關的單個輻射量,在這裏表示爲L。輻射度用於量化光的強度或強度。 來自一個方向。 首先要理解是有些棘手的,因爲輻射是多個物理量的組合,因此我們將首先關注這些物理量:

輻射通量: 輻射通量Φ是以瓦特爲單位的光源的透射能量。 光是在多個不同波長上的能量的總和,每個波長與特定(可見)顏色相關。 因此,可以將光源的發射能量視爲其所有不同波長的函數。 390nm至700nm(納米)之間的波長被認爲是可見光譜的一部分,即人眼能夠感知的波長。 在下面,您可以找到一張不同波長的日光能量圖像:

在這裏插入圖片描述

輻射通量測量該功能在不同波長下的總面積。 在計算機圖形學中直接將這種波長測量作爲輸入是不切實際的,因此我們經常簡化表示輻射通量的過程,而不是將其表示爲變化的波長強度的函數,而是將其表示爲以RGB編碼的光色三元組(或者通常稱爲 它:light color)。 這種編碼確實會損失很多信息,但是對於視覺方面通常可以忽略不計。

立體角: ω表示的立體角告訴我們投影到單位球體上的形狀的大小或面積。 投影到該單位球體上的形狀的面積稱爲立體角。 您可以將立體角可視化爲體積的方向:

在這裏插入圖片描述

輻射強度: 輻射強度是測量單位球面上每立體角的輻射通量或光源在投影面積上的強度。例如,給定一個向各個方向均勻輻射的全向光,其輻射強度是在一個特定的區域(立體角)上給我們能量:

在這裏插入圖片描述

輻射強度的描述方程定義如下:

在這裏插入圖片描述
輻射強度 I 等於輻射通量Φ比立體角ω。

有了輻射通量,輻射強度和立體角的知識,我們可以最終描述輻射方程,該方程被描述爲輻射強度Φ的光的立體角ω上區域A上的總觀測能量:

在這裏插入圖片描述

輻射度是對區域中的光量的輻射度量,該區域由光相對於表面法線的入射(或入射)角θ進行縮放:光越弱,則直接照射到表面的強度就越弱,而當光垂直於垂直於表面時強度最大。 這類似於我們在基本照明教程中對漫射照明的感知,因爲它直接對應於光線的方向向量和曲面法線之間的點積:

float cosTheta = dot(lightDir, N);  

輻射方程非常有用,因爲它包含了我們感興趣的大多數物理量。如果我們認爲立體角ω 和麪積A無限小,則我們可以使用輻射率來測量入射到空間中單個點的單束光線的通量。 這種關係使我們能夠計算出影響單個(片段)點的單個光線的輻射度。 我們有效地將立體角轉換爲方向向量和點。 這樣,我們可以直接在着色器中使用輻射率來計算單個光線對每個片段的貢獻。

實際上,我們通常關心的是所有入射光到p點的情況p點是所有光的總和,也就是輻照度。有了輻射和輻照度的知識,我們可以回到反射率方程:

在這裏插入圖片描述

我們現在知道,L在呈現方程代表了一些點p和傳入的無限小的立體角ωi的輻射率, ωi可以認爲是傳入的方向向量ωi。請記住,這是根據光相對於表面的入射角cosθ來縮放能量的,在反射率方程中我們可以找到n⋅ωi。反射方程計算的點p (p,ωo)在方向ωo的輻射率Lo(p,ωo)總和,ωo的方向爲觀看者的方向。或者換句話說:Lo測量的是從ωo方向的p點輻照度總和。

由於反射率方程基於輻照度,輻照度是所有入射輻射之和,因此我們不僅測量單個入射光方向的光,而且還測量半球內所有入射光方向的光 Ω 以點爲中心 p。一種半球 可以描述爲圍繞表面法線n對齊的半球形 :

在這裏插入圖片描述

要計算區域或半球(例如半球)內部的值的總和,我們使用稱爲 積分 在反射率方程中表示爲 ∫ 在所有傳入方向上 dωi 在半球內 Ω。積分用於衡量函數的面積,該面積可以通過解析或數字方式進行計算。由於對渲染和反射率方程都沒有解析解,因此我們希望以數值方式離散求解積分。這轉化爲取半球上反射方程的較小離散步長的結果Ω並在步長上求平均值。這就是所謂的黎曼和 ,我們可以大致將代碼可視化如下:

int steps = 100;
float sum = 0.0f;
vec3 P    = ...;
vec3 Wo   = ...;
vec3 N    = ...;
float dW  = 1.0f / steps;
for(int i = 0; i < steps; ++i) 
{
    vec3 Wi = getNextIncomingLightDir(i);
    sum += Fr(P, Wi, Wo) * L(P, Wi) * dot(N, Wi) * dW;
}

通過按dW縮放步長,總和將等於積分函數的總面積或體積。 可以將縮放每個離散步長的dW視爲反射率方程式。 從數學上講,它是我們計算積分所用的連續符號,儘管它不直接與代碼中的dW相關(因爲這是Riemann和的離散步驟),但它有助於以這種方式進行思考。 請記住,採取離散步驟將始終使我們大致瞭解函數的總面積。 細心的讀者會注意到,我們可以通過增加步數來提高黎曼和的精度。

反射率方程式將按該命中點縮放的半球上所有入射光方向的輻射求和,並返回觀察者方向上反射光的總和。 傳入輻射可以來自我們熟悉的光源,也可以來自我們將在IBL教程中討論的測量每個傳入方向輻射的環境圖。
讀者會注意到,我們可以通過增加步數來提高黎曼和的精度。

反射率方程式將按該命中點縮放的半球上所有入射光方向的輻射求和,並返回觀察者方向上反射光的總和。 傳入輻射可以來自我們熟悉的光源,也可以來自我們將在IBL教程中討論的測量每個傳入方向輻射的環境圖。

現在唯一不爲人知的是fr符號,稱爲BRDF或雙向反射分佈函數,它根據表面的材料特性縮放或稱量入射輻射。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章