本文翻譯自Scratchapixel 3.0[1],是一個關(guān)于計算機圖形學(xué)的系統(tǒng)性的學(xué)習(xí)教程。如果有誤,歡迎在評論區(qū)討論。
光線追蹤的另一個優(yōu)點是,通過擴展光線傳播的思想,我們可以非常容易地「模擬反射」和「折射」等效果,這在模擬玻璃材料或鏡面表面時非常方便。在一篇名為《用于陰影顯示的改進照明模型》的 1979 年論文中,Turner Whitted 首次描述了如何擴展 Appel 的光線追蹤算法以進行更高級的渲染。Whitted 的想法擴展了 Appel 發(fā)射光線的模型,以包括反射和折射的計算。
在光學(xué)中,反射和折射是眾所周知的現(xiàn)象。雖然后面的課程將專門講解反射和折射,但我們將研究模擬它們所需的內(nèi)容。我們將以具有折射和反射特性的玻璃球為例。只要我們知道與球相交的光線的方向,就很容易計算它發(fā)生的情況。反射和折射方向都基于交點處的法向量和入射光線(主光線)的方向。為了計算折射方向,我們還需要指定材料的折射率。雖然我們之前說過光線直線傳播,但我們可以將折射可視化為光線彎曲。當(dāng)光子撞擊不同介質(zhì)(因此折射率不同)的物體時,其方向會改變。這個科學(xué)將在后面更深入地討論。只要我們記住這兩個效應(yīng)取決于法向量和入射光線方向,而折射取決于材料的折射率,我們就可以繼續(xù)前進。同樣,我們還必須意識到像玻璃球這樣的物體同時具有反射和折射性質(zhì)。我們需要計算給定表面上的兩者,但是我們?nèi)绾位旌纤鼈??我們將反射結(jié)果的 50%與折射結(jié)果的 50%混合嗎?不幸的是,它比那更復(fù)雜。值的混合取決于主光線(或視角方向)和物體法線以及折射指數(shù)之間的角度。幸運的是,一個方程可以精確地計算每個值應(yīng)該如何混合。這個方程被稱為菲涅耳方程。為了保持簡潔,我們現(xiàn)在只需要知道它的存在,并將幫助確定混合值。
圖1:使用光學(xué)定律計算反射和折射光線。
讓我們回顧一下。Whitted 算法如何工作?我們從眼睛發(fā)射主光線,并與場景中的物體最近的交點(如果有)相交。如果光線擊中不是漫反射或不透明的物體,我們必須進行額外的計算工作。為了計算例如玻璃球上的那個點的結(jié)果顏色,你需要計算反射顏色和折射顏色并將它們混合。記住,我們需要分三步進行。計算反射顏色,計算折射顏色,然后應(yīng)用菲涅耳方程。
首先,我們計算反射方向。為此,我們需要兩個項目:交點處的法向量和主光線的方向。一旦我們獲得反射方向,我們發(fā)射一個新光線?;氐轿覀兊呐f例子,假設(shè)反射光線擊中了紅色球。使用 Appel 的算法,我們通過向光源發(fā)射陰影光線來確定達(dá)到紅色球上那個點的光線量。這將獲得顏色(如果被遮擋則為黑色),乘以光強度并返回到玻璃球的表面。
現(xiàn)在,我們對折射做同樣的事情。因為光線穿過了玻璃球,所以它被稱為傳輸光線(光線從球的一側(cè)傳輸?shù)搅硪粋?cè);已傳輸)。為了計算傳輸方向,我們需要交點處的法向量,主光線方向和材料的折射率(在這個例子中,它可能是類似于玻璃材料的 1.5)。使用計算出的新方向,折射光線繼續(xù)到玻璃球的另一側(cè)。在那里,因為它改變了介質(zhì),所以光線又被折射了一次。正如你在相鄰的圖像中看到的那樣,當(dāng)光線進入和離開玻璃物體時,光線的方向會改變。每當(dāng)有介質(zhì)變化時都會發(fā)生折射,而光線退出的介質(zhì)和進入的介質(zhì)具有不同的折射率??諝獾恼凵渎史浅=咏?1,而玻璃的折射率約為 1.5。折射會使物體在看不同折射率的物體時或通過不同折射率的物體看時出現(xiàn)偏移。假設(shè)當(dāng)折射光線離開玻璃球時,它擊中了綠色球。我們通過發(fā)射陰影光線計算了綠色球和折射光線之間的交點處的局部照明。然后,將顏色(如果被遮擋則為黑色)乘以光強度并返回到玻璃球的表面。
最后,我們計算菲涅耳方程。我們需要玻璃球的折射率,主光線與命中點法線之間的角度。使用點積(我們將在稍后解釋),菲涅耳方程返回兩個混合值。
以下是一些偽代碼,以加強它的工作方式:
// compute reflection colorcolor reflectionCol = computeReflectionColor();
// compute refraction colorcolor refractionCol = computeRefractionColor();
float Kr; // reflection mix valuefloat Kt; // refraction mix value
fresnel(refractiveIndex, normalHit, primaryRayDirection, &Kr, &Kt);
// mix the two colors. Note that Kt = 1 - KrglassBallColorAtHit = Kr * reflectionColor + Kt * refractionColor;
在上面的代碼中,我們在注釋中寫道Kt = 1 - Kr。換句話說,Kr + Kt = 1。這是因為在自然界中,光線不能被創(chuàng)造或摧毀。因此,如果一些入射光被反射,那么剩余的入射光(未被反射的部分)必然會被折射。如果你將反射和折射光的總和相加,它等于入射光的量。通常,菲涅耳方程為我們提供了Kr和Kt的值(如果它做正確的事情,它們的總和應(yīng)該等于 1),因此你可以直接使用函數(shù)返回的值。然而,如果我們只有其中一個,這就足夠了。如果你有Kr,你可以得到Kt(1-Kr)。如果你有Kt,你可以得到Kr(1-Kt)。
這個算法最后一個美妙的事情是它是「遞歸」的(這在某種程度上也是一種詛咒!)。在我們研究的情況下,反射光線擊中了一個紅色的不透明球體,折射光線擊中了一個綠色的、不透明的、散射的球體。然而,我們會想象紅色和綠色的球體也是玻璃球。要找到反射和折射光線返回的顏色,我們必須對紅色和綠色球體使用與原始玻璃球相同的過程:也就是說,向場景中射入更多的反射和折射光線。這是射線跟蹤算法的一個缺點,有時會成為一個頭痛的問題。想象一下我們的相機在一個只有反射面的盒子里。理論上,光線被困住了,將會無限地反彈在盒子的墻壁上(或者直到你停止模擬)。因此,我們必須設(shè)置一個任意的限制,防止光線相互作用,從而無限遞歸。每次光線反射或折射時,它的深度都會增加。當(dāng)光線深度大于最大遞歸深度時,我們停止遞歸過程。你的圖像不一定會看起來完全準(zhǔn)確,但是有一個近似的結(jié)果總比沒有結(jié)果好。
-
追蹤算法
+關(guān)注
關(guān)注
2文章
9瀏覽量
7625 -
計算機圖像
+關(guān)注
關(guān)注
2文章
5瀏覽量
2236 -
光線追蹤
+關(guān)注
關(guān)注
0文章
183瀏覽量
21458
發(fā)布評論請先 登錄
相關(guān)推薦
評論