[從零開始計算機圖形學]之二漫反射
顏色模擬
上面寫到我們需要展示 的顏色,那麼 都顏色究竟應該是怎樣的?應該就是它自身的顏色和光相互作用的結果,我們這裡命事物本身顏色為c, P點處光的強度為i(這裡我們只考慮白光), 那麼比如 就會是最終的顏色,一般來說 0 < i < 1,比如 i 是 0.5,那麼物體就會變成原來的一半亮。
以下的模擬,有些會用到自然界中可能事物的真實樣子,有些就是純粹的數學模型。
1.光源
1.1 環境光
環境光很簡單,我們直接給一個數字 這樣就代表了周圍環境的光
1.2 點光源
點光源就像電燈泡一樣,固定於一個點,然後發出光線於四周,對於點光源,我們只需它的位置Q和強度 .
1.3 方向光
方向光就類似於自然界中的太陽光,我們需要知道它的方向 和強度 .
2 光與物體
2.1 漫反射
漫反射是這樣,達到物體表面的表面的光實際上只有 在 方向的投影,實際上P點得到的強度是 .
注意我們只考慮 大於0的狀況,因為如果小於零,它是到達了物體的背面。
為了計算方便,令 表示我們指向光源的方向, 為物體表面的法向量:
當然我們也可以為了計算方便,選擇
可以得到光疊加的效果是:
至此,我們就可以畫出空間中很好看的效果了。注意再次提醒這裡後面的疊加部分只需要算大於0的部分,因為小於0的光疊加是沒有物理意義的。
至此の偽碼
跟蹤光線與球相交 IntersectRaySphere
跟之前寫的一樣
t1 處的光ComputeLighting
在以下的偽碼中,P是物體表面的位置,N是物體表面的法向量。
ComputeLighting(P, N) {
i = 0.0
for light in scene.Lights {
if light.type == ambient {
i += light.intensity
} else {
if light.type == point
L = P - light.position //指向光的方向
else
L = -light.direction //指向光的方向
n_dot_l = dot(N, L)
if n_dot_l > 0
i += light.intensity*n_dot_l/(length(N)*length(L))
}
}
return i
}
t1 的顏色TraceRay
這裡我們在空間里放入好幾個球體,然後計算t1處的顏色偽碼如下:
TraceRay(O, D, t_min, t_max){
closest_t = inf
closest_sphere = NULL
for sphere in scene.Spheres {
t1, t2 = IntersectRaySphere(O, D, sphere)
if t1 in [t_min, t_max] and t1 < closest_t
closest_t = t1
closest_sphere = sphere
if t2 in [t_min, t_max] and t2 < closest_t
closest_t = t2
closest_sphere = sphere
}
if closest_sphere == NULL
return BACKGROUND_COLOR
P = O + closest_t * D #交點P的位置
N = P - closest_sphere.center #計算P處的法向量
N = N / length(N) #normalize 法向量
return closest_sphere.color * ComputeLighting(P, N)
}
畫到畫布上
看結果:
效果已經比之前好很多了。
KrisYu/computer-graphics-from-scratch-Notes推薦閱讀: