(RayTracing) 카메라 움직이기
카메라는 유전체처럼 디버깅하기 힘듭니다. 그래서 나는 항상 천천히 기능을 추가하며 개발합니다. 첫번째로 시야(FOV, Field of View)를 조정가능하게 해봅시다. 저희 이미지는 정사각형이 아니기 때문에, 수평/수직으로 봤을 때 각각이 다릅니다. 저는 항상 수직 시야를 사용합니다. 생성자에 각도를 받아 사용자의 취향에 맞게 바꿀 수 있게 합니다.
카메라 각도의 기하
난 항상 광선이 원점에서 시작해 z = -1 평면을 향하게 합니다. 거리 비율에 따라 h를 늘려 z=-2 평면이나 그 이상을 만들 수 있습니다.
$h = tan ( \frac {\theta}{2})$로 우리 카메라를 바꿨습니다:
asp...
(RayTracing) 유전체
물, 유리, 다이아몬드 처럼 투명한 재질은 유전체입니다. 광선을 맞았을 때, 광선은 반사광과 굴절광으로 나뉩니다. 둘중 무작위로 하나만 선택하게 두고, 유전체에 대한 광선을 처리합니다.
굴절
디버깅이 가장 어려운것은 굴절된 광선이기 때문에, 굴절된 광선먼저 진행합니다.
스넬의 법칙
스넬의 법칙에서 굴절의 공식을 알 수 있습니다.
\[\eta \cdot sin \theta = \eta' \cdot sin \theta'\]
θ와 θ’는 법선에서의 각도입니다. η와 η’(“에타”와 “에타 프라임”)은 굴절률(공기=1.0, 유리=1.3-1.7,다이아몬드=2.4)이다.
굴절된 각도를 얻기위해, $sin \t...
(RayTracing) 메탈
다른 재질을 시도해볼 차례입니다. Material 추상 클래스를 이용해서 캡슐화할 겁니다. Material은 다음 두가지 기능이 필요합니다.
광선 생산
반사된 광선 약화
data Material =
forall a. Scatterable a =>
Material a
data Scattered =
Scattered
{ scatteredRay :: Ray
, attenuationColor :: Vec3 Float
}
class Scatterable a where
scatter :: (RandomGen g) => a -> Ra...
(RayTracing) 난반사 재질
구의 재질을 만들어 볼 차례입니다. 난반사 재질로 시작해봅시다. 여기서 떠오르는 의문점은 물체과 재질을 분리(재질을 여러개의 물체에 할당) 할 것인지 묶어(재질과 물체가 연결된 절차적 물체에 유용) 볼것인지 입니다. 여기서는 분리- 대부분의 렌더링에서 사용하는-할 것이고, 각 방식에 장단점이 있음을 유의합시다.
단순한 난반사 재질
난반사 물체는 빛을 발산하지 않는 대신에 고유의 색으로 조절한뒤 반사합니다. 난반사 표면에 반사되는 빛은 무작위 방향을 가집니다. 3개의 빛을 나란히 발사했지만 모두 각기 다른 방향을 향합니다.:
난반사는 반사보다 흡수하는 성질을 가집니다. 어두운 표면일수록 더 흡수를 많이합니다...
(RayTracing) 안티앨리어싱
현실의 카메라로 찍은 사진은 아래 이미지 처럼 계단현상은 거의 보이지 않을 것 입니다. 사진은 픽셀이 물체와 배경이 섞이기 때문입니다. 저희도 픽셀을 샘플링한 후 평균을 내는 것으로 비슷한 효과를 만들어 낼 수 있습니다.
랜덤 유틸리티
일반적인 범위인 $0 \leq r < 1$에서 실수를 반환하는 랜덤 생성기가 필요합니다. “1보다 작다”라는 점은 몇가지 이점이 있기 때문에 중요합니다.
저는 하스켈의 random 패키지의 RandomGen instance와 randomR 함수를 사용합니다.
샘플링으로 픽셀 생성
한 픽셀에 $n_s$개 만큼의 무작위 광선을 쏴 결과를 평균냅니다.
아래는 샘플링...
(RayTracing) 법선 셰이딩과 Hittable 추상화
법선으로 셰이딩 만들어보기
이제 물체의 여부 뿐만 아니라, 셰이딩을 적용해봅시다. 아직 빛이나 다른 요소를 추가하지 않았으니, 법선(normal vector)을 색으로 표현합니다. 법선은 교점에서 수직입니다. 외향법선(outward normal)은 구의 중심에서 접점을 뺀 방향을 가집니다. 법선을 만들때 두가지 고려사항이 있습니다.
첫번째 고려사항은 단위 법선 벡터입니다. 셰이딩에서 단위벡터를 사용하는 관습이 있긴하지만, 코드에 꼭 적용해야 하는 것은 아닙니다. 대부분의 구조가 그렇듯 개인의 자유를 따릅니다.
법선벡터 → 단위벡터 → 0~1 → normalize → x/y/z ⇒ r/g/b 순서로 변환합...
(RayTracing) 구 그리기
레이트레이서에 이제 물체 하나를 추가해봅시다. 광선이 구에 부딪혀 다양한 각도로 반사되기 때문에 레이트레이싱 예제에 적합합니다.
광선-구 교점
반지름이 R이고 원점이 중심인 구의 방정식은 $x^2 + y^2 + z^2 = R^2$입니다. 바꿔말해서
점 $(x, y, z)$가 구 위: $x^2 + y^2 + z^2 = R^2$
점 $(x, y, z)$가 구 안: $x^2 + y^2 + z^2 < R^2$
점 $(x, y, z)$가 구 밖: $x^2 + y^2 + z^2 > R^2$
구의 중심이 $(C_x, C_y, C_z)$ 일때 방정식:
\[(x - C_x)^2 + (y - C_y...
(RayTracing) Ray, 카메라, 배경
레이트레이서는 광선를 따라가 픽셀의 색을 추정합니다. 광선을 함수로 생각해보면 $P(t) = A + tB$입니다. P는 3D 공간에서 선을 그리는 1차 방정식이고, A는 원점, B는 방향, 실수 t는 광선의 변수입니다. 변수 t에 따라 P(t)는 직선 위의 점을 움직입니다. t를 양수로 두면, A의 앞으로만 직진할 수 있습니다. 이를 반직선 혹은 광선이라고 부릅니다.
함수 P(t)는 코드에서 at ray t 로 표현합니다.
module Ray where
import Vector
data Ray =
Ray
{ origin :: Point
, direction ::...
78 post articles, 10 pages.