개요

기존 Whitted Ray Tracing의 단점을 극복하고자, 여러개의 랜덤한 광선을 사용하여 렌더링하는 기법이다. Cook 이 1984년에 발표하였다.

안티 얼리어싱

Antialiasing.png

많은 방법이 있지만, 그중 좋은 방식은 격자를 나누고 랜덤한 부분을 선택하는 방식이다. 만약 격자를 나누지 않으면 물체가 움직이기 시작하면 지터링이 너무 심하게 나오게 된다. 이 방식은 격자를 안나누는 방식에 비해 지터링이 훨씬 괜찮게 나온다. 또한 랜덤한 변수를 선택하는 이유는 랜덤할 경우 규칙적인 패턴이 없어지면서 훨씬 자연스럽게 나오기 때문이다.

[math]c(x,y)=c(x,y)+trace(x+\frac{p+\epsilon_1}{n},y+\frac{p+\epsilon_2}{n})\\c(x,y)=c(x,y)/n^2[/math]

Soft Shadows

그냥 shadow ray를 사용하면 그림자가 너무 정직하게 생겨버린다. 부드러운 그림자 효과를 내기 위해서 area light 에서 랜덤한 부분과 shadow ray 검사를 한뒤 평균을 내는 방식으로 soft shadow를 구현한다.

[math]l_{pos} = c+\epsilon_1 a + \epsilon_2 b [/math]

Depth of field (DOF)

DOF.png

카메라의 렌즈가 점이라면 깊이감이 들어가지 않는다. 그러나 카메라의 렌즈가 점이 아니라면 초점이 맞춰지는 대상과 깊이감이 들어가게 된다. 카메라의 렌즈에서 한점을 랜덤하게 고른뒤 광선을 발사한다. (이때 안티얼리어싱때문에 픽셀에서도 랜덤한 한 점이 잡히게 된다.) 여러개의 광선이 발사되 평균되면서 초점이 맞지 않는 대상은 DOF효과가 구현되게 된다.


pseudo Code

glm::vec3 random = parameters.lensRadius * randomP; //렌즈의 크기만큼 랜덤한 지점을 고른다.
glm::vec3 originOffset = u * random.x + v * random.y; //빛을 발사하는 원점에 더할 오프셋을 카메라의 u v 좌표를 참고하여 구한다. 
return ne::Ray(origin + originOffset, bottomLeft + s * horizontal + t * vertical - origin - originOffset); 
//구해진 오프셋을 더한 원점과 방향은 픽셀위의 한점 (여기선 s,t) 이 되도록 빛을 발사한다.

Motion Blur

물체가 움직이면서 생기는 잔상을 처리하기 위해서 사용된다. 시간을 평균낸다음 시간 간격사이에서 램덤하게 물체의 위치를 잡고 레이트레이싱을 한다. 나온 결과를 평균내면 Motion Blur 가 구현되게 된다.

  1. Set time interval[math][T_0,T_1][/math]
  2. Randomly choose a time t
  3. Ray tracing with object transform with t
  4. Averaging the result

이건 단순한 케이스이고 만약 복잡한 케이스일 경우는 구간을 나누어서 표현하게 된다. 등속도 운동이 아니면 속도함수를 구한뒤, 그 커브를 이용해서 non linear interpolation 하면 된다.

Glossy reflections

모든 물체가 Lambertian이나 거울처럼 이상적인 반사분포(BRDF)를 가지는 것은 아니다. 흔히 보이는 대부분의 물체는 부분적인 반사분포를 가진다. 그러한 물체는 반사범위에 있는 점을 랜덤하게 결정한뒤 레이트레이싱한후 평균내면 원하는 결과가 나오게 된다.

Pseudo Code

r_out = ne::Ray(hit.p, reflected + roughness_*randomSphere()); 
레이를 만들면서 반사된 지점에 roughness를 곱한 랜덤 스피어를 더해서 랜덤함을 부여한 반사를 만든다.