日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实时高清渲染:全局光照(Global Illumination)[2]---漫反射/高光全局光照

發布時間:2023/12/31 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实时高清渲染:全局光照(Global Illumination)[2]---漫反射/高光全局光照 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

漫反射全局光照:

表面的預計算光照:

定向表面預光照:

預計算轉移(PRT):

存儲格式:

動態漫反射全局光照:

RSM:

LPV:

基本步驟:

步驟1簡述:

步驟2簡述:

步驟3簡述:

步驟4簡述:

基于體素的方法:

VXGI:

屏幕空間方法:

高光全局光照:

IBL:

split sum approximation:

預濾波環境貼圖:

預計算BRDF:

基于體素的方法:

平面反射:

屏幕空間的方法:

SSR:

學習資料:

全局光照[1]導航:

實時高清渲染:全局光照(Global Illumination)[1]_This is MX的博客-CSDN博客_實時全局光照https://blog.csdn.net/m0_56399931/article/details/123302771

前記:前面opengl的文章內容可能得晚些更新了,因為有些效果在bgfx上面實現了,不適合放帶代碼了-------------------------------------------------------------------------------------------------------------博主:mx

漫反射全局光照:

表面的預計算光照:

預先計算的輻照度值通常與漫反射顏色或反照率映射相乘,存儲在一個單獨的紋理集。雖然從理論上講,出射度(輻照度時間漫反射顏色)可以預先計算并存儲在一組紋理中,但在大多數情況下,許多實際考慮排除了這種選擇。顏色映射通常是相當高的頻率,它們利用各種各樣的平鋪,并且它們的部分經常在模型中重復使用,所有這些都是為了保持合理的內存使用。輻照度值通常要低得多,而且不容易重復使用。將光照和表面顏色分開會消耗更少的內存。

除了最嚴格的硬件平臺外,現在很少使用預先計算的輻照度。根據定義,輻照度是針對給定法線方向計算的,因此我們不能使用法線映射來提供高頻細節。這也意味著輻照度只能為平面預先計算。如果我們需要在動態幾何上使用烘焙照明,我們需要其他方法來存儲它。這些限制促使人們尋找使用定向組件存儲預計算光照的方法。

定向表面預光照:

最常用的方法是存儲完整的球面輻照度信息,例如使用球面諧波。該方案首先由Good和Taylor在加速光子映射的背景下提出,并由Shopf等人在實時環境中使用。在這兩種情況下,定向輻照被存儲在紋理中。如果使用9個球面諧波系數(三階SH),質量很好,但存儲和帶寬成本較高。使用4個系數(二階SH)成本更低,但很多細微之處會丟失,光照對比度更低,法線貼圖也不太明顯。Chen使用了Halo方法的一種變體,這種方法是為了以更低的成本獲得三級SH的質量而開發的。他從球面信號中提取出最主要的光,并分別以顏色和方向的形式存儲。剩余部分用二階SH編碼。這將系數的數量從27減少到18,質量損失很小。Hu描述了如何進一步壓縮這些數據。Chen和Tatarchuk提供了他們在生產中使用的基于gpu的烘烤管道的進一步信息。Habel等人提出的h基是另一種解決方案。由于它只編碼半球面信號,較少的系數就可以提供與球面諧波相同的精度。僅用6個系數就可以獲得與三階SH相當的質量。因為基只定義在一個半球上,我們需要在這個表面上的一些局部坐標系來正確地定位它。通常,由uu、參數化產生的切線幀用于此目的。如果將h基分量存儲在紋理中,其分辨率應該足夠高,以適應底層切線空間的變化。如果多個具有顯著不同切線空間的三角形覆蓋同一像素,重建信號將不精確。

球面諧波和h偏移的一個問題是它們都表現出ringing現象。雖然預過濾可以減輕這種效果,但它也可以平滑照明,這可能并不總是理想的。此外,即使是成本較低的變體,在存儲和計算方面也有相對較高的成本。在更嚴格的情況下,如在低端平臺或在虛擬現實渲染時,這種費用可能是令人望而卻步的。成本是簡單的替代方案仍然流行的原因。《半衰期2》使用自定義的半球形基礎,存儲三個顏色值,每個樣本總共9個系數。環境/高光/方向(AHD)為基礎的布局也是一個流行的選擇,盡管它很簡單。它已經被用于《使命召喚》系列和《最后生還者》等游戲中。參見圖11.23。Crytek在《孤島驚魂》中使用了這種變體。Crytek表示法由切線空間的平均光方向、平均光色和標量方向因子組成。最后一個值用于混合環境和方向組件,它們都使用相同的顏色。這將每個樣本的存儲系數減少到6個:三個值用于顏色,兩個值用于方向,一個用于方向因子。Unity引擎也在其中一個模式中使用類似的方法。這種類型的表示是非線性的,這意味著,技術上,線性插值單個組件,無論是在像素還是頂點之間,都不是數學正確的。

如果我們需要關于任意方向照明的信息,而不僅僅是在表面上的一個半球內(例如,為動態幾何提供間接照明),我們可以使用編碼完整球面信號的方法。球面諧波在這里是很自然的。當內存不太受關注時,三階SH(每個顏色通道9個系數)是最受歡迎的選擇;否則,使用二階(每個顏色通道4個系數,這匹配RGBA紋理中的組件數量,所以一個地圖可以存儲一個顏色通道的系數)。球面高斯也適用于全球面,因為波瓣可以分布在整個球面上,也可以只分布在法線周圍的半球上。環境立方體貼圖也是一個可行的選擇。

預計算轉移(PRT):

如果我們假設場景的幾何形狀沒有變化,只改變了燈光,我們就可以預先計算光線如何與模型交互。 物體間的效果,如相互反射或次表面散射,可以預先分析到一定程度,并將結果存儲起來,而無需對實際radiance值進行操作。 將入射光線轉化為整個場景中radiance分布的描述的函數稱為傳遞函數。 預先計算傳遞這個的解決方案稱為預先計算傳遞或預計算radiance傳遞(PRT)方法。

PRT通常采用球諧函數來存儲數據,球面諧波(Spherical Harmonics,簡稱SH)基函數是一組定義在球面上基函數。每個SH基函數由伴隨勒讓德多項式給出。

SH基函數具備一個的良好性質:正交完備性,不同的基函數之間相互正交,即有:

任何一個關于三維方向ω的函數f(ω)都可以轉換成球面函數,該函數在SH基函數Bi(ω)下的權重計算(即投影)公式為:

投影之后,再用ci權重帶入如下公式

可以對原始函數f(ω)進行復原,這個過程我們稱之為重建。

我們來看反射方程:

我們把L(i)展開,記為:

把V(i)ρ(i,o)max(0,n?i)展開記為:

帶回反射方程,得到:


再根據正交完備性,上述式子可以簡化為:


這下我們輕而易舉的知道,如果我們能夠計算出li和ti,那么反射方程結果就是這兩個乘積的和。

對于l和t的計算:

l的計算如下:

t的計算如下:

對于diffuse的BRDF,其本身與ωo無關,因此ωo無論如何變化,在預計算階段我們都可以直接忽略。但如果是glossy材質,fr是會隨著觀察視角ωo的變化而變化的!為此,對于glossy材質的BRDF,我們寫成如下形式:

即對于glossy材質,我們需要增加一個變量ωo進行打表。遍歷ωo的離散取值,為每一個不同的ωo生成一個light transport向量t(ωo),因此glossy材質的tt是一個矩陣,矩陣規模為m×n,其中m是SH基函數個數,n是ωo離散化個數。對于glossy材質,計算最終的光照輻射率時是l向量和t矩陣的矩陣向量乘。

存儲格式:

光照貼圖是存儲預計算光照最常見的方法之一。 存儲特定類型的數據時也稱為irradiance貼圖,光照貼圖被用來統稱所有這些數據。 在運行時,GPU的內置紋理機制將會被使用。 通常是GPU中的值都是雙線性過濾的,對于某些表示可能不是完全正確的。 例如,當使用AHD表示時,濾波后的D(方向)分量在插值后將不再是單位長度,因此需要進行重新歸一化。 使用插值還意味著A(環境值)和H(高光值)并不完全是我們在采樣點直接計算的結果。 也就是說,結果通常看起來是可以接受的,即使表示是非線性的。

在大多數情況下,光照貼圖不能使用mipmapping,因為光貼圖的分辨率比典型的反照率貼圖或法線貼圖小。 即使在高質量的應用中,一個光貼圖的紋素至少可以覆蓋大約20× 20厘米的面積,通常還會更多。 使用這種尺寸的像素,額外的mip級別幾乎是不需要的。

為了在紋理中存儲光照信息,物體需要提供一個獨特的參數。當將漫反射顏色紋理映射到一個模型上時,通常網格的不同部分使用相同的紋理區域是很好的,特別是當一個模型的紋理具有一般的重復模式時。光照貼圖重用是非常困難的,光照對于網格上的每個點都是獨特的,所以每個三角形都需要在光照地圖上占據自己獨特的區域。創建參數化的過程從將網格分割成更小的塊開始, 這既可以使用一些啟發式自動完成,也可以使用工具手動完成。通常情況下,已經存在于其他紋理映射中的分割被使用。接下來,對每個chunk進行獨立參數化,確保其各部分在紋理空間中不重疊,紋理空間中生成的元素稱為圖表(charts)或殼(shells), 最后,所有圖表都打包到一個共同的紋理中,如下圖:

光線被baking到一個場景中,光照貼圖應用到表面上。 光照貼圖使用一種獨特的參數化, 場景被劃分為多個元素,這些元素被壓平并打包成一個共同的紋理。 例如,左下角的剖面對應于地面,顯示了立方體的兩個陰影。

必須小心確保圖表不僅不重疊,而且它們的過濾足跡(filtering footprints)必須保持分離。當渲染一個給定的圖表時,所有可以訪問的像素(雙線性濾波訪問四個相鄰的像素)都應該被標記為使用過的,這樣就不會有其他圖表與它們重疊,否則,圖表之間可能會出現bleeding現象,其中一個圖表的光照可能會在另一個圖表上可見。盡管為光照貼圖系統提供一個用戶控制的“gutter”量用于燈光地圖圖表之間的間距是相當普遍的,但這種分離是不必要的。使用一組特殊的規則,可以在光照貼圖空間中對圖表進行柵格化,從而自動確定圖表的正確過濾足跡。

看上圖:為了準確地確定一個圖表的過濾足跡,我們需要找到渲染期間可以訪問的所有紋素。 如果一個圖表與四個相鄰像素中心之間的正方形相交,那么所有這些像素都將用于雙線性濾波。 紋素網格用實線標記,紋素中心用藍點,圖表用粗實線進行柵格化(左)。 我們首先將圖表柵格化為移動了半像素大小的網格,并以虛線(中間)標記。 任何接觸標記單元格的紋素都被認為占用(右)。

Greger等人提出了irradiance volume,通過irradiance環境貼圖的稀疏空間采樣表示五維(三個空間和兩個方向)irradiance函數。 也就是說,在空間中有一個三維網格,在每個網格點上都有一個irradiance環境貼圖。 動態對象從最近的貼圖中插值irradiance值。 Greger等人使用兩級自適應網格進行空間采樣,但也可以使用其他體積數據結構,如八叉樹。

存儲的樣本點irradiance函數的最常見表示包括:

  • 球諧(SH)的二階和三階,前者更常見,因為一個顏色通道所需的四個系數方便地打包到四個紋理的通道。
  • 球形的高斯函數(Spherical Gaussians)。
  • 環境立方體或環境六面體(dice)。

irradiance volume也可以為靜態表面提供光照, 這樣做的好處是不必為光照貼圖提供單獨的參數化, 這種技術也不會產生裂縫。 靜態和動態物體都可以使用相同的表示,使兩種幾何類型之間的光照一致。 在延遲著色(第20.1節)中,體積表示很方便使用,其中所有光照都可以在一次pass中執行, 其主要缺點是內存消耗比較大。 光照貼圖所使用的內存大小與分辨率的平方成正比; 對于一個規則的體積結構,它與立方體一起增長。 由于這個原因,網格體積表示使用了相當低的分辨率。 自適應、分層形式的光照Volumes具有更好的特性,但它們仍然比光照貼圖存儲更多的數據, 它們也比有規則間隔的網格慢,因為額外的在著色器代碼中創建加載依賴,這可能導致更慢的執行。

Unity引擎使用一個四面體網格來插值一組光照探針。

從一個四面體網格中采樣的光照質量高度依賴于網格的結構,而不僅僅是probes的總體密度。 如果它們不均勻分布,產生的網格可能包含產生視覺artifacts的細長四面體。 如果用手放置probes,問題可以很容易地糾正,但這仍然是一個手動過程。 四面體的結構與場景的幾何結構沒有關系,所以如果處理不當,燈光將會在墻壁上插入并產生bleading artifacts,就像irradiance volume一樣。 在手動放置probes的情況下,可以要求用戶插入額外的probes以防止這種情況發生。 當使用自動放置probes時,可以在probes或四面體上添加某種形式的可見性信息,以將其影響限制在相關區域。

對靜態和動態物體使用不同的光照存儲方法是一種常見的做法。 例如,靜態網格可以使用光照貼圖,而動態對象可以從體積結構中獲得光照信息。 雖然很受歡迎,但這種方案可以在不同類型的幾何形狀之間創建不一致的外觀。 其中的一些差異可以通過regularization來消除,在regularization中,光照信息在表示中被平均。

動態漫反射全局光照:

盡管預計算光照可以產生非常好的效果,但它的主要優點也是它的主要缺點——它需要預計算, 這種離線流程可能會很長。 在典型的游戲關卡中,光照baking需要花費數小時的時間。 因為光照計算需要很長時間,美工通常被迫同時處理多個關卡,以避免等待baked完成時的停工時間。 這反過來又會導致用于渲染的資源負載過大,并導致bakiing時間更長。 這種循環會嚴重影響生產力并導致挫敗感。 在某些情況下,甚至不可能預先計算光照,因為幾何圖形在運行時發生變化或在某種程度上由用戶創建。

Tabellion和Lamorlette表明,在許多情況下,一次bounces就足以產生令人信服的結果。 這是一種離線方法,但它啟發了Dachsbacher和Stamminger的一種方法,即反射陰影貼圖(RSM)。

類似于常規陰影貼圖,反射陰影貼圖是從光線的角度渲染的。 除了深度之外,它們還存儲了其他有關可見表面的信息,如反照率、法線和直接光照(通量)。 當執行最后的著色時,RSM的像素被當作點光源來提供間接照明的單一bounce。 因為一個典型的RSM包含成百上千個像素,所以使用重要性驅動的啟發式只選擇其中的一個子集。 Dachsbacher和Stamminger后來展示了如何通過反射過程來優化該方法, 即不是從RSM中為每個著色點選擇相關的像素,而是基于整個RSM和屏幕空間中的splatted創建一些燈。

該方法的主要缺點是它不能為間接照明提供遮擋, 雖然這是一個近似,但結果看起來是可信的,并且在許多應用程序中是可接受的。

為了達到高質量的效果,并在光傳輸時保持時間穩定,需要創建大量的間接光。 如果創建的太少,它們往往會在RSM重新生成時迅速改變它們的位置,并導致閃爍現象。 另一方面,從性能的角度來看,過多的間接光源是一個挑戰。 Xu描述了該方法是如何在《神秘海域4》中執行的。 為了保持在性能限制范圍內,他在每個像素上使用少量的光,但是在幾個幀上循環使用不同的光集,并暫時過濾結果,如圖:

人們提出了不同的方法來解決間接遮擋的不足。 Laine等人使用雙拋物面陰影貼圖作為間接光源,但將它們增量地添加到場景中,因此在任何一幀中只有少量的陰影貼圖被渲染。 Ritschel等人使用簡化的、基于點的場景表示來渲染大量不完美的陰影貼圖。 當直接使用時,這樣的貼圖很小,包含很多缺陷,但經過簡單的過濾后,提供了足夠的保真度,為間接照明提供適當的遮擋效果。

RSM:

這里講一下RSM。

基本思想:

在第一個Pass,RSM算法需要記錄哪些場景面元被直接光照照亮,將這些被直接光照照亮的面元幾何信息和著色信息存儲記錄下來;所以第一個pass會從光源視角渲染整個場景

在第二個Pass,根據前面得到的直接光照照亮面元的信息,計算這些面元對其他場景物體的光照。

這里計算其實是rsm比較難想的一個地方,后面會專門出一期講各種全局光照算法的文章,到時候再細講。

LPV:

基本步驟:

  • (1)直接光照的信息生成;
  • (2)將直接光照得到的虛擬光源注入到三維體素網格中;
  • (3)體素網格之間的輻射率擴散、傳播;
  • (4)根據傳播得到的輻射率進行間接光照的計算。

步驟1簡述:

在步驟(1)中,LPV算法從光源的角度渲染整個場景,然后將深度信息、頂點位置、法線向量和反射通量保存到貼圖紋理當中。

步驟2簡述:

在步驟(2)時,創建一個三維的體素網格(3D紋理),然后根據貼圖的信息,將有幾何體的貼圖像素當作一個虛擬光源,根據貼圖上存儲的頂點位置找到其對應的體素格子,將反射通量注入保存到這個體素格子中,從而完成虛擬光源注入的過程。

每個體素網格的中心可以看成是一個點光源。但值得注意的是,格子中心的點光源并不是向所有方向均勻輻射的!因為在注入階段,格子中心僅僅在某些方向被注入了虛擬光源。因此,為了描述格子中心向不同方向的輻射情況,LPV采用了球面諧波函數來描述其球面方向上的輻射率分布情況。

LPV論文的作者采用了前兩階(也就是前四個)球面諧波函數來存儲格子中心的輻射率分布。

步驟3簡述:

步驟(3)的體素格子之間的輻射率傳播采用迭代擴散的方式進行。在每一次迭代過程中,每個體素格子向與其直接相鄰的格子傳播輻射率(下圖所示,三維情況是6個相鄰格子)。依次迭代下去,直到一定的迭代次數,論文實踐表明4次的迭代能夠取得不錯的效果。

步驟4簡述:

最后的步驟(4)其實不言自明。在計算過程的時候,找到著色點對應的體素格子,從中取出球面諧波的權重系數,還原出給定方向上的輻射率,完成間接計算的過程。

基于體素的方法:

VXGI:

場景體素化:

基于GPU的三維體素化大致思想就是:首先計算出需要體素化模型的AABB包圍盒,然后將模型投影到AABB包圍盒的某個平面上,經過渲染管線的光柵化插值操作,我們可以在片元著色器得到每個像素點對應的世界空間的頂點坐標,根據這個頂點坐標標記三維空間數組(這個三維空間數組就是根據體素劃分的空間序列)的相應位置,最后在CPU端讀出這個三維空間數組,若當前的數組位置有標記,則將該數組位置對應的立方體作為一個體素。可以看到,整個流程思路非常清晰,但是還需要借助一些手段修正算法存在的缺陷,修補方法這里就不多講了。

直接光照pass:

生成了3D體素紋理之后,緊接著的步驟是直接光照的Pass。直接光照Pass可以直接借用RSM機制來實現,即從光的視角來渲染整個場景,將直接光照的數據存儲到貼圖中,然后再將貼圖里面的直接光照數據注入到場景體素化的3D紋理當中。然后再為這些3D紋理生成Mipmap,如下圖所示(Clipmap本質上就是在Mipmap的基礎上加了個裁剪范圍,使得顯存只需要加載每個Mipmap層次的一部分,這里不細說)

間接光照pass:

間接光照Pass是從攝像機的角度渲染整個場景,并根據上面的Mipmap結構對場景發射射線進行追蹤來計算間接光照部分。這里發射追蹤的射線是具有一定角度的圓錐體。但圓錐體也并不是真正意義上的圓錐體,而是由不同level的體素拼接而成的類錐體的形狀,如下圖所示,從近到遠,體素的大小逐漸增大。

VXGI可以實現非常驚艷的全局光照效果,但是它的缺點也顯而易見:3D紋理太過耗費顯存,體素化的精度決定了光照精度,而且也存在一些漏光的artifact現象。

屏幕空間方法:

漫反射的屏幕空間方法主要有ssao,ssdo,基于raymarching的ssgi吧

ssao和ssdo的區別主要是ssdo對于每一個采樣點p,對比該采樣點的深度與該采樣點對應到的深度貼圖上的深度,如果采樣點被遮擋了(深度值大于貼圖上的深度值),那么就計算遮擋位置的直接光照信息作為p點的間接光照(例如A點對應的橙色點),而ssao這一部分僅僅計算遮擋值。

SSDO當然也不是物理準確的,上圖的最右邊圖片所示,A點對應的z1點并不會對p點產生間接彈射的貢獻,但是他缺取用了。并且,采樣的半球半徑限制了彈射范圍,只有在半球半徑范圍內的點才會被考慮進來,因此不會渲染超過一定范圍內的間接彈射效果。最后需要注意的就是,SSDO是基于屏幕空間的,因此它所有的間接光照信息都來源于當前攝像機能夠看到的,對于那些看不到的面元,自然也就不會貢獻間接光照的效果。

高光全局光照:

IBL:

這里只講述ibl的鏡面ibl反射項

split sum approximation:

我們將反射方程分割成這樣

預濾波環境貼圖:

split sum之后的方程左邊稱為預濾波環境貼圖。它類似于輻照度圖,是預先計算的環境卷積貼圖,但這次考慮了粗糙度。因為隨著粗糙度的增加,參與環境貼圖卷積的采樣向量會更分散,導致反射更模糊,所以對于卷積的每個粗糙度級別,我們將按順序把模糊后的結果存儲在預濾波貼圖的 mipmap 中。例如,預過濾的環境貼圖在其 5 個 mipmap 級別中存儲 5 個不同粗糙度值的預卷積結果,如下圖所示:

表面越粗糙則反射得越模糊得現象其實涉及到一個反射波瓣的問題,所以的反射波瓣就是反射光線的分布范圍。如下圖5所示,對于一個光滑的完美鏡面,其反射波瓣就是反射向量,越粗糙則反射波瓣越大,且基本上都是以反射向量為中心。

所以我們需要做重要性采樣。 為了加速蒙特卡洛積分方法的收斂速度,Epic Games公司提出使用超均勻分布序列(Low-discrepancy Sequence)——Hammersley序列。相對于普通的偽隨機數,Hammersley序列的隨機數分布更加均勻,如下圖6所示,將其應用到蒙特卡洛采樣能夠提升收斂速度。

然后我們需要將這個二維的序列轉換成我們對半球方向的三維采樣,同樣我們利用球面坐標和笛卡爾坐標之間的關系,首先將Hammersley序列xi=(u,v)T∈HN映射到(?,θ),然后轉換成笛卡爾坐標下的向量形式。一個均勻映射和一個余弦映射公式如下:

我們將結合之前PBR提到的法線分布函數,法線分布函數給定一個法線向量,它返回微平面法線與給定法線朝向一致的分布概率。Trowbridge-Reitz GGX法線分布函數的數學定義為:

我們將法線分布函數與余弦映射結合起來做重要性采樣:

然后根據上面的知識我們就能夠計算預濾波環境貼圖,后面就不多講了。

預計算BRDF:

這部分實際上就比較簡單,我們把各種情況的BRDF存到一張紋理上,這個紋理通常被稱作lut。這張紋理的u坐標為粗糙度,v為cos(n*l),我們輸入這兩個值就能夠獲得對應的brdf結果。

但是原始的brdf函數積分基于三個變量,cos(n*1),粗糙度,F0(菲涅爾方程輸入的基礎值),我們需要簡化一下這個方程:

將Fresnel-Schlick 近似公式替換右邊的F,可以得到:

在簡單拆分一下:

這樣我們就能夠構建基于n?ωo和粗糙度roughness的二維查找表了,在實現中,我們通常渲染屏幕空間大小的四邊形,遍歷n?ωo和粗糙度的所有取值,計算上述公式的兩項積分的結果,存儲為紋理的像素值vec2(左邊積分結果,右邊積分結果)。

基于預濾波環境貼圖和預計算的BRDF,我們很容易得到IBL的高光反射項了。

基于體素的方法:

我們考慮VXGI的高光反射項,在VXGI的慢反射項中我們需要對各個方向都做體素追蹤,但是對于高光反射項我們只需要對反射方向做體素追蹤,然后在這個方向上做光照計算就可以。

平面反射:

平面反射最主要的是做在平面的對稱另一側做一個虛擬相機,然后渲染一次場景,把結果作為一張render texture,然后我們可以把這張render texture作為全局光照的高光反射項,通過矩陣變換來求出著色點需要采樣的位置。做這個方法需要做一個合適的裁剪面,因為在反射面的遠側(即后面)的物體不應該被反射,這個平面的近平面應該與平面重合。

屏幕空間的方法:

SSR:

基本思想:

ssr的基本思想比較簡單,根據gbuffer里面存儲的數據,取每個fragment然后計算出reflect方向,然后以這個fragment位置和reflect做ray的origin和dir,做raymarching,如果打到物體則做光照計算作為間接光照。

著重講一下raymarching部分,每一次光線步進,我們都會做一次相交判斷。相交判斷的邏輯為:將當前的步進點pp的深度值與pp點對應的深度貼圖上的深度值進行大小判斷,如果pp點的深度值大于深度圖貼圖上的深度值,那么就說明當前步進的點落到某個場景表面之下,這時就發生了相交。最為Naive的光線步進就是Linear Ray-marching,也就是每次步進一小段固定的距離。

問題:

光線步進是在三維世界空間做的,所以每一次都要把步進的點投影到屏幕上。但是在三維空間做固定長度的光線步進,投影到屏幕上步進的間隔并非均勻的。這就會出現兩個問題,遺漏采樣和重復采樣。看下面這個圖:

左圖越紅代表重復采樣的次數越多,右圖表示均勻采樣。

解決方法:

可以把處理全部都轉化到屏幕空間中,即對于線段起始點 Q0 和結束點 Q1 ( Q0,Q1 是世界空間的點),首先將其轉換到屏幕空間中得到點 H0,H1 (屏幕空間中的點是二維點只有 x,y 分量)。如此一來對于點 Q0,Q1 就可以借助DDA畫線算法的思想來進行采樣(原本的畫點操作就變成了采樣操作)。這樣的好處就在于絕不會重復采樣,也保證會連續采樣。

注意:由于在屏幕空間進行Ray Marching丟了 Z 值信息,無法進行深度比較,因此還需要單獨保存當在屏幕空間從 H0 變化到 H1 的 Z 值。

學習資料:

核心:《Real-Time Rendering》 Chapter 11 Global Illumination

1.理論 - LearnOpenGL CN

2.【《Real-Time Rendering 3rd》 提煉總結】(八) 第九章 · 全局光照:光線追蹤、路徑追蹤與GI技術進化編年史 - 知乎

3.蒙特卡洛積分 - 知乎

4.從NDC(歸一化的設備坐標)坐標轉換到世界坐標的數學原理 - 愛碼網

5.法線貼圖 - LearnOpenGL CN

6.11.5 漫反射全局光照 - 知乎

7.高質量實時渲染:實時環境光 | YangWC's Blog

8.Global Illumination_Screen-Space Ray Tracing(SSR)_沉默的舞臺劇的博客-CSDN博客

總結

以上是生活随笔為你收集整理的实时高清渲染:全局光照(Global Illumination)[2]---漫反射/高光全局光照的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。