games101 – 4 – Ray Tracing
- 2022 年 1 月 7 日
- 筆記
- programming-and-computer-graphics, 電腦圖形學 - 渲染
games101 – 4 – Ray Tracing
- games101 – 4 – Ray Tracing
- 為什麼需要Ray Tracing
- Recursive (Whitted-Style) Ray Tracing
- Ray-Surface Intersection
- Bounding Volumes
- Spatial Partitions
- Bounding Volume Hierarchy (BVH)
- Radiometry
- Bidirectional Reflectance Distribution Function (BRDF)
- 反射方程
- 渲染方程
- Understanding the rendering equation
- Probability Review
- Monte Carlo Integration
- Path Tracing
- Materials and Appearances
- 沒有覆蓋到的內容
對應的Lecture 13 ~ 17
為什麼需要Ray Tracing
光柵化無法處理全局效果
- 軟陰影;
- 光反彈次數超過一次的情況,如glossy reflection,indirection illumination;
- 光柵化的很快,但是品質比較低;
- raytracing,很準確,但是很慢;
Recursive (Whitted-Style) Ray Tracing
An improved Illumination model for shaded display」 T. Whitted, CACM 1980
Ray-Surface Intersection
射線的定義:\(r(t) = o + td, 0 \le t \lt \infty\),一個起始點,和方向構成了一個射線。
對於射線和方程隱式表示的表面,可以通過求解方程式得到交點。更常見的場景是射線和三角網格模型進行求交計算。對於射線和三角形求交計算,可以先和平面進行求交,然後再判斷交點是不是位於三角形內部。
(23條消息) Möller-Trumbore演算法-射線三角形相交演算法_zhanxi1992的專欄-CSDN部落格
O – P_0 = (P_1 – P_0)b_1 + (P_2 – P_0)b_2 – tD \\
S = E_1b_1 + E_2b_2 -tD
\]
矩陣的形式表示如下:
-D & E_1 & E_2
\end{bmatrix}
\begin{bmatrix}
t \\
b_1 \\
b_2
\end{bmatrix} = S
\]
然後利用克萊姆法則(\(Ax = c=>x_i = detA_i/detA\))求解,
如果遍歷三角網格中的所有三角形,對每個三角形進行相交計算,並找到最近的交點,整個過程是非常耗時的。需要的開銷為#pixels x #triangles (x #bounces)
.
Bounding Volumes
可以利用包圍盒,進行加速。針對複雜物體,構建出包圍盒,然後如果射線不和包圍盒相交,那麼射線就不和包圍盒內部的物體相交,如果相交,然後再進行內部物體的相交測試,而包圍盒相交監測速度非常快。常見的包圍盒有:包圍球,軸對⻬包圍盒,非軸對齊包圍盒。更常用的是使用軸對齊包圍盒,因為針對它的相交計算很簡單。
在計算直線和Axis-Aligned Box相交的時候(此處允許t<0),分別針對每個維度,計算出\(t_{min}\)和\(t_{max}\),那麼\(t_{enter}\)等於各個維度\(t_{min}\)的最大值,\(t_{exit}\)等於各個維度\(t_{max}\)的最小值。如果\(t_{enter} < t_{exit}\),那麼相交。
但是ray並不是一條直線需要對負值的情況進行額外判斷:
- 如果\(t_{exit} < 0\),那麼不相交;
- 如果\(t_{exit} \ge 0\)並且\(t_{enter} < 0\),那麼射線的原點位於box內部,相交;
- 那麼ray和AABB相交,當且僅當\(t_{enter} < t_{exit}\ \&\& \ t_{exit} \ge 0\)
Spatial Partitions
- Uniform Spatial Partitions (Grids) 適用於很多對象均勻的分布在空間中的場景。
更常用的是不均勻空間劃分。
常見的分法如下:
K-D Tree – OI Wiki (oi-wiki.org)
Bounding Volume Hierarchy (BVH)
構建一個BVHs,需要進行如下操作:
- 找到包圍盒;
- 將包圍盒中的對象分成兩個部分(細分的時候需要選擇維度最大的方向進行劃分,這裡通常選擇當前node軸長最大的軸,切分的位置通常位於中間);
- 重新計運算元集的包圍盒;
- 達到某種條件後中斷,通常是node中的對象少於一定數量;
- 將對象存儲到各個節點中;
BVH的數據結構主要分為兩類:內部節點和葉子節點。內部節點包括:包圍盒,子節點;葉子節點包括:包圍盒,對象集合;
BVH樹的遍歷:
Intersect(Ray ray, BVH node) {
if (ray misses node.bbox) return;
if (node is a leaf node)
test intersection with all objects;
return closest intersection;
hit1 = Intersect(ray, node.child1);
hit2 = Intersect(ray, node.child2);
return the closer of hit1, hit2;
}
Radiometry
radiant energy: the energy of electromagnetic radiation. \(Q\ [J=Joule]\); 能量整體
radiant flux: the energy emitted, reflected, transmitted or received, per unit time. \(\Phi = dQ/dt\),單位是[W=Watt],或者是[lm = lumen]。單位時間的能量;
另外幾個關鍵概念,示意圖如下:
Radiant intensity: the power per unit solid angle emitted by a point light source. \(I(\omega) = d\Phi/d\omega\),單位是[W/sr],或者是[lm/sr = candela]。單位時間單位立體角的能量;立體角的概念,微分,積分,如下:
Irradiance:the power per (perpendicular projected) unit area incident on a surface point.\(E(x) = d\Phi(x)/dA\)。單位面積單位時間的能量(面積為垂直於光線方向);面積理解的示意圖如下:
Radiance: the power emitted, reflected, transmitted or received by a surface, per unit solid angle, per projected unit area. 示意圖及公式如下:
irradiance和radiance概念對比,irradiance表示的是單位面積接收到的所有能量,radiance表示,從某一個單位立體角看過去的單位面積上接收的能量。
Bidirectional Reflectance Distribution Function (BRDF)
BRDF: 用來表示從每個方向過來的光線,有多少會貢獻到每個outgoing方向。represents how much light is reflected into each outgoing direction \(\omega_r\) from each incoming direction. 對應的公式如下:
上面的公式中為什麼需要對Lr做微分,對Ei做微分呢?具體解釋可以參見:關於BRDF公式理解的筆記_fatever的部落格-CSDN部落格,摘錄關鍵內容如下:
反射方程
表示的不同方向的irradiance對出射方向上的貢獻的積分。
渲染方程
在反射方程的基礎上再加上emission項,得到渲染方程。
Understanding the rendering equation
圖中,當一個光源的時候,用間接反射光取代了入射光。
Probability Review
隨機變數的概率密度函數:\(P(a\le x\lt b) = \int_a^b p(x) dx\)。p(x)即為概率密度函數。從負無窮到正無窮的圖形對應的面積為1。對應的期望為\(E(X) = \int xp(x)dx\).
Monte Carlo Integration
蒙特卡羅方法(Monte Carlo Method)概述——概念、起源、思路、應用、特點、計算程式、計算舉例和文獻資料(21k) (sohu.com)
蒙特卡洛光線追蹤技術_Dezeming的部落格-CSDN部落格
如果需要求解定積分,\(\int_a^bf(x) dx\),首先需要知道x的概率分布,那麼可以轉換成求解積分,\(\int_a^bf(x)/p(x)\cdot p(x) dx\),那麼用蒙特卡洛進行期望估計,得到:
Path Tracing
Whitted-Style Ray Tracing的條件是:總是執行鏡面反射和折射;碰到漫反射表面停止。這種近似對於一些場景會存在問題:1)對於glossy reflection表面;2)在diffuse材質,不會有反射;
之前給出的rendering equation是正確的,那麼如何求解呢?
A Simple Monte Carlo Solution
問題:假設我們需要渲染下面場景中一個點(僅考慮直接光照):
那麼可以得到如下的反射方程:
\]
要求解這樣的積分,我們利用蒙特卡洛積分,構建「f(x)”,為:\(L_i(p,\omega_i)f_r(p,\omega_i, \omega_o)(n\cdot\omega_i)\),並且先假設\(\omega_i\)的概率密度函數為\(p(\omega_i)=1/(2\pi)\),半球上均勻分布,那麼可以得到:
如果在光線追蹤的時候,一條光線hit到了物體,而沒有hit到light,需要怎麼處理呢?那麼首先需要計算hit到物體的位置,貢獻的光是多少。如下:
shade(p, wo)
Randomly choose N directions wi~pdf
Lo = 0.0
For each wi
Trace a ray r(p, wi)
If ray r hit the light
Lo += (1/N) * L_i * f_r * cosine / pdf(wi)
Else If ray r hit an object at q
Lo += (1/N) * shade(q, -wi) * f_r * cosine / pdf(wi)
Return Lo
這樣就ok了么,並不然。上述的處理方式還存在什麼問題呢?
問題1:光線次數隨著碰撞次數的增多而指數增長
問題1:光線次數隨著碰撞次數的增多而指數增長。如下圖所示:
為了避免光線數量的暴增。隨機只選擇一條光線進行處理。如下:
shade(p, wo)
Randomly choose 1 directions wi~pdf
Lo = 0.0
Trace a ray r(p, wi)
If ray r hit the light
Lo += L_i * f_r * cosine / pdf(wi)
Else If ray r hit an object at q
Lo += shade(q, -wi) * f_r * cosine / pdf(wi)
Return Lo
這種方式的話,如果一個像素上只有一條光線穿過,那麼得到的結果雜訊會很大,因此需要多條射線穿過一個像素位置,然後對結果進行平均。這樣針對一個像素位置的偽程式碼如下:
ray_generation(camPos, pixel)
Uniformly choose N sample positions within the pixel
pixel_radiance = 0
For each sample in the pixel
Shoot a ray r(camPos, cam_to_sample)
If ray hit the screen at p
pixel_radiance += 1 / N * shade(p, sample_to_cam)
Return pixel_radiance
問題2:此時shade函數如何終止
問題2:此時shade函數中還存在一個問題,就是函數進行無限循環。解決方案是提供輪盤賭的方式(Russian Roulette)。假設我們手動設置一個概率值,P,在發射一條光線的時候,給出一個隨機值,如果範圍在P~1,那麼返回:0,否則返回:Lo/P。這樣得到的Lo的期望為:E = P * (Lo/P) + (1-P)*0 = Lo。將這部分內容加到shader偽程式碼中如下:
shade(p, wo)
Manully specify a probability P_RR
Randomly select ksi in a uniform dist. in [0, 1]
If (ksi > P_RR) return 0.0
Randomly choose ONE direction wi-pdf(w)
Trace a ray r(p, wi)
If ray r hit the light
Return L_i * f_r * cosine / pdf(wi) / P_RR
Else If ray r hit an object at q
Return shade(q,-wi) * f_r * cosine / pdf(wi) / P_RR
問題3:如何提高取樣效率
上述的實現並不是很高效,如下圖所示:
如果光源面積比較大,那麼發射較少數量的光線,就可以碰撞到光源,如果光源面積比較小,那麼需要發生很多的光線才行。這樣如果我們在半球表面進行均勻取樣,那麼會有大量的光線是wasted的。那麼怎麼解決呢?
可以將取樣分為兩部分,1)針對光源進行取樣,2)針對非直接光照場景進行取樣;
從渲染方程得知,接收到的光照資訊,是針對立體角進行積分的,那麼怎麼轉換到,通過光源面積進行積分呢?從立體角的定義得到:
\]
那麼渲染方程可以重寫為:
此時shade偽程式碼可以寫為:
shade(p, wo)
# Contribute from the light source
Uniformly sample the light at x' (pdf_light = 1/A)
# test blocked
Shoot a ray from p to x'
If the ray is not blocked in the middle
L_dir = L_i * f_r * costheta * costheta' / |x' - p|^2 / pdf_light
# Contribute from other reflectors
L_indir = 0.0
Test Russian Roulette with probability P_RR
Uniformly sample the hemisphere toward Wi (pdf_hemi = 1/2pi)
Trace a ray r(p, wi)
If ray hit a non-emitting object at q
L_indir = shade(q, -wi) * f_r * costheta / pdf_hemi / P_RR
Materials and Appearances
Materials == BRDF。BRDF用來表示從每個方向過來的光線,有多少會貢獻到每個outgoing方向。
Snell’s Law
傳輸方向從i到t,那麼如果\(\eta_i/\eta_t > 1\)可能發生完全內反射(即,沒有折射的現象)。
Fresnel Reflection
用來解釋:視線垂直於表面時,反射較弱,而當視線非垂直表面時,夾角越小,反射越明顯,這一種現象。
Fresnel Reflection – 菲涅爾反射 – Tekkaman – 部落格園 (cnblogs.com)
準確解和近似解分別如下:
微表面
微表面,針對每一個元素都可以視為mirror。
沒有覆蓋到的內容
- uniformly sampling the hemisphere; How?
- Monte carlo integration allows arbitrary pdfs. What’s the best choice?
- Do random numbers matter ? Yes! (low discrepancy sequences)
- I can sample the hemisphere and the light. Can I combine them? Yes! (multiple imp. sampling)
- The radiance of a pixel is the average of radiance on all paths passing through it. Why? (pixel reconstruction filter)
- Is the radiance of a pixel the color of a pixel? No. (gamma correction, curves, color space)
- deeper path tracing.