ray vector는 half line을 사용하여 구현하였습니다. 시작점인 viewpoint를 p라고 하고, view direction을 d라고 하였을 때 ray vector r(t) = p + t*d로 나타낼 수 있습니다. 이 때 구해야 할 값은 t값이 됩니다. t값을 구하기에 앞서 먼저 각 픽셀별로 view direction을 구해주어야 합니다. view direction을 구하기 위해서는 pixel-to-image mapping 방법을 사용해 주었습니다.
u = l + (r-l)(i+0.5)/n_x
v = b + (t-b)(j+0.5)/n_y
위는 pixel-to-image mapping 방법에 대한 이해를 도와주는 그림입니다. 주어진 직사각형이 image plane이 되고 우리는 그 image plane 속의 픽셀에 각각 ray vector를 만들어 주어야 합니다. 좌표를 이용하는 방법 보다는 vector의 합을 이용하여 구하는 것이 편리합니다.
먼저 image plane의 중점으로 가는 vector w는 normal vector를 사용하여 구하였습니다. 그 후 u벡터와 v벡터를 view up vector를 사용하여 구해주었습니다.
1
2
3
|
그리고 이 벡터들을 이용하여 (0,0)의 위치로 가는 start vector를 구해주었고 이중 for문을 돌며 image plane의 width와 height을 픽셀 수로 나누어준 길이 즉 픽셀 하나의 가로 세로 크기만큼 더해주며 픽셀별 ray vector를 구해주었습니다.
1
2
3
4
5
|
ray = start + u_unit * x * pixel_x + pixel_y * y * v_unit
tmp = raytrace(list, ray, view.viewPoint)
img[y][x] = shade(tmp[0], ray, view, list, tmp[1], light)
|
이렇게 구해준 ray vector를 raytrace에 인자로 넘겨주어 도형 list를 돌며 결과값을 반환해주었습니다. 이 결과값은 추후에 설명하겠습니다.
raytrace 함수에서는 어떤 도형이 가장 view point와 가까운지와 그 도형과의 거리를 return합니다. 가장 가까운지 판별하는 방법은 sphere와 box가 다른 방법을 사용하고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
for i in list:
if i.__class__.__name__ == 'Sphere':
if b ** 2 - a * c >= 0:
idx = cnt
idx = cnt
elif i.__class__.__name__ == 'Box':
result = 1
txmin = (i.minPt[0]-viewPoint[0])/ray[0]
txmax = (i.maxPt[0]-viewPoint[0])/ray[0]
if txmin > txmax:
txmin, txmax = txmax, txmin
tymin = (i.minPt[1]-viewPoint[1])/ray[1]
tymax = (i.maxPt[1]-viewPoint[1])/ray[1]
if tymin > tymax:
tymin, tymax = tymax, tymin
if txmin > tymax or tymin > txmax:
result = 0
if tymin > txmin:
txmin = tymin
if tymax < txmax:
txmax = tymax
tzmin = (i.minPt[2]-viewPoint[2])/ray[2]
tzmax = (i.maxPt[2]-viewPoint[2])/ray[2]
if tzmin > tzmax:
tzmin, tzmax = tzmax, tzmin
if txmin > tzmax or tzmin > txmax:
result = 0
if tzmin >= txmin:
txmin = tzmin
if tzmax < txmax:
txmax = tzmax
if result == 1:
if m >= txmin:
m = txmin
idx = cnt
cnt = cnt + 1
|
intersect 거리를 구하는 방법은 다음 두 페이지를 참조하였습니다.
https://pjreddie.com/media/files/Redmon_Thesis.pdf
'컴퓨터 그래픽스' 카테고리의 다른 글
[파이썬을 이용한 Ray Tracing 구현] 5. shade와 그림자 생성 (3) | 2019.05.05 |
---|---|
[파이썬을 이용한 Ray Tracing 구현] 3. xml 파싱 및 클래스 생성 (0) | 2019.05.05 |
[파이썬을 이용한 Ray Tracing 구현] 2. PyCharm 설치하기 (0) | 2019.05.04 |
[파이썬을 이용한 Ray Tracing 구현] 1. Ray Tracing이란? (0) | 2019.05.04 |