<aside> ⁉️ 궁금한 내용, 오타, 수정사항, 문의사항은 아래 깃허브 이슈 혹은 노션 블록 댓글로 달아주시면 바로 확인해드립니다! 도움이 되셨다면 아래 링크를 통해 🌟 한번 꾹 눌러주세요 ‼️
</aside>
GaepoMorningEagles/mini_raytracing_in_c
이번 장에서는 광선이 오브젝트를 hit했을 때의 정보(교점의 위치와 albedo, 교점에서의 법선 등)를 저장할 hit_record라는 구조체에 대해 알아볼 것이다.
hit_record 구조체에 대해 알아보고 구조체를 만든다.
4단원과 5단원에서 작성했던 hit_sphere함수의 return 값에 대해 생각해보자. 4단원에서는 hit_sphere 함수는 광선이 구를 hit했는지 아닌지를 확인할 수 있는 값을 return 했고, 5단원에서는 primary ray의 origin과 교점 사이의 거리에 해당하는 값을 return 했다.
하지만 hit했는지 아닌지 여부만으로는 충분하지 않다. origin과 교점 사이의 거리만으로도 부족하다. 광선을 추적하고 이미지를 렌더링하기 위해서는 더 많은 정보가 필요하다. 우선 교점의 정확한 위치가 필요하다. 교점의 위치를 알아야 교점에서의 법선 벡터를 알 수 있고, 법선 벡터를 알아야 광원이 오브젝트에 미치는 영향을 계산할 수 있다. 그러므로 이러한 정보들을 저장할 구조체가 필요하다.
다음과 같은 구조체를 만들어서 structures.h에 추가해주자.
...
///추가
typedef struct s_hit_record t_hit_record;
...
///추가
struct s_hit_record
{
t_point3 p;
t_vec3 normal;
double tmin;
double tmax;
double t;
t_bool front_face;
};
Code1 : [miniRT/include/structures.h]
p는 교점의 좌표, normal은 교점에서의 법선, t는 광선의 원점과 교점 사이의 거리이다. tmin과 tmax, front_face가 무엇인지, 왜 필요한지는 이번 장에서 더 설명할 것이다. 교점에서의 색깔 등 추가적으로 필요한 정보는 교재를 따라가며 필요할 때 t_hit_record 구조체 안에 추가해주도록 하자.
hit 했을 때의 정보를 저장할 hit record 구조체를 만들었으니 적용을 해보자.
...
t_color3 ray_color(t_ray *ray, t_sphere *sphere)
{
double t;
t_vec3 n;
//추가
t_hit_record rec;
rec.tmin = 0;
rec.tmax = INFINITY;
//추가 끝
//제거
t = hit_sphere(sphere, ray);
if (t > 0.0)
{
n = vunit(vminus(ray_at(ray, t), sphere->center));
return (vmult(color3(n.x + 1, n.y + 1, n.z + 1), 0.5));
}
//제거 끝
//추가
if (hit_sphere(sphere, ray, &rec))
return (vmult(vplus(rec.normal, color3(1, 1, 1)), 0.5));
//추가 끝
...
Code2 : [miniRT/src/trace/ray/ray.c]
tmin과 tmax는 무엇일까? 우리는 광선 벡터를 t에 관한 매개 방정식