陰影

我們追蹤一條光線,考慮它碰到的物體,考慮光碰到物體表面發生的漫反射和鏡面反射。

在考慮了這些問題以上,我們還有並沒有考慮到的問題--影。

影子說起來也很容易考慮,就是如果在某點與光之間有物體阻礙的話,那麼這點將是沒有光的,否則這點是被點亮的。

方向光

我們依舊用L來指向光源,考慮我們想研究的P點狀況:

對於P點來說,由它出髮指向方向光的路上如果碰到阻礙,那麼就說明P點應該為暗,否則P點為亮。

這裡實際上我們依舊有工具來計算一條射線與球的最近相交點了,所以工具可以繼續使用,這裡的 t_{min} = 0, t_{max} = +∞

點光源

對於點光源來說

指向光源的L我們很容易我們也容易求得,是 Q - P , 不過這裡對應的 t_{min} = 0, t_{max} = 1 ,因為別忘了我們的L是用來指向光源的, t_{min} = 0 就是物體本身所處位置, t_{max} = 1 就是點光源所在位置。

這裡我們還需要注意一點,那就是我們需要當 t = 0 時,實際上物體會在它本身上留下陰影,所以我們取一個極小的t值,比如 t = 0.001 來處理這種狀況。

環境光

至於環境管,它是均勻分布的,就不用考慮它了。

至此の偽碼

ClosestIntersection

這是提取出來,我們用來算從某點射出射線D在給定 t_min, t_max 的情況下跟球的相交和最近的交點。

ClosestIntersection(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
}

return closest_sphere, closest_t
}

TraceRay

TraceRay依舊不變,依舊是算的這條光線應該看到的顏色。

TraceRay(O, D, t_min, t_max){
closest_sphere , closest_t = ClosestIntersection(O, D, t_min, t_max)

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, -D, sphere.specular)
}

ComputeLighting

在這裡我們增加了檢查陰影的部分,如果我們中間碰到了阻礙,那麼我們就不用計算光了,它就是暗色 i = 0,否則我們才計算響應的顏色,這裡還採用了 0.001 來避免物體在其自身的表面形成陰影。

ComputeLighting(P, N, V, s) {
i = 0.0
for light in scene.Lights {
if light.type == ambient {
i += light.intensity
} else {
if light.type == point {
L = light.position - P
t_max = 1
}
else {
L = light.direction
t_max = inf
}

# shadow check
shadow_sphere, shadow_t = ClosestIntersection(P, L, 0.001, t_max)
if shadow_sphere != NULL
continue

# diffuse
n_dot_l = dot(N, L)
if n_dot_l > 0
i += light.intensity*n_dot_l/(length(N)*length(L))

# specular
if s!= -1 {
R = 2*N*dot(N,L) -L
r_dot_v = dot(R, V)
if r_dot_v > 0
i += light.intensity*pow(r_dot_v/length(R)*length(V)),s)
}
}
}
return i
}

畫到畫布上

看結果:

KrisYu/computer-graphics-from-scratch-Notes?

github.com
圖標

推薦閱讀:
相关文章