[minirt]#8オブジェクト構造体
同じ実習資料と同じです.元の資料を調べることをお勧めします.
コードには1つの物体しか配置されていませんが、複数の物体を配置して光を照射する必要があります.まず、魔推進物体をレンダリングします.
さまざまな物体を配置し、接続リストで感知を1つずつブラウズしてチェックします.
構造体の作成
コードには1つの物体しか配置されていませんが、複数の物体を配置して光を照射する必要があります.まず、魔推進物体をレンダリングします.
さまざまな物体を配置し、接続リストで感知を1つずつブラウズしてチェックします.
構造体の作成
コード#コード#
ray_color.c
//광선이 최종적으로 얻게된 픽셀의 색상 값을 리턴.
t_color3 ray_color(t_ray *ray, t_object *world)
{
t_hit_record rec;
rec.tmin = 0;
rec.tmax = MAX;
if (hit(world, ray, &rec)) // 모든 구조체에 대한 정보를 담은 연결리스트 world로 광선과의 충돌을 테스트한다.
return (vmult(vplus(rec.normal, color3(1, 1, 1)), 0.5));
else
{
// (1-t) * 흰색 + t * 하늘색
return (color3(0.5, 0.5, 0.5));
}
}
hit.c
#include "trace.h"
t_bool hit(t_object *world, t_ray *ray, t_hit_record *rec)
{
t_bool hit_anything;
t_hit_record *temp_rec;
temp_rec = rec;
hit_anything = FALSE;
while (world) // world->next로 훑어가며 등록된 구조체를 전부 체크함
{
if (hit_obj(world, ray, temp_rec))
{
hit_anything = TRUE;
temp_rec->tmax = temp_rec->t;
rec = temp_rec;
}
world = world->next;
}
return (hit_anything);
}
t_bool hit_obj(t_object *world, t_ray *ray, t_hit_record *rec)
{
t_bool hit_result;
hit_result = FALSE;
if (world->type == SP)
hit_result = hit_sphere(world, ray, rec);
return (hit_result);
}
hit_sphere.c
#include "structures.h"
#include "utils.h"
#include "trace.h"
static void print_vec(t_vec3 vec3)
{
printf ("x : %f, y : %f, z : %f\n", vec3.x, vec3.y, vec3.z);
}
t_bool hit_sphere(t_object *world, t_ray *ray, t_hit_record *rec)
{
t_sphere *sp = world->element;
t_vec3 oc; // 0에서부터 벡터로 나타낸 구의 중심.
t_vec3 normal; // 법선 벡터, 표준 벡터가 아니다!
//a, b, c는 각각 t에 관한 근의 공식 2차 방정식의 계수
double a;
double half_b; // b가 half_b로
double c;
double discriminant; // 판별식
double sqrtd;
double root;
oc = vminus(ray->orig, sp->center);
a = vlength2(ray->dir);
half_b = vdot(oc, ray->dir);
c = vlength2(oc) - sp->radius2;
discriminant = half_b * half_b - a * c;
// printf ("a : %f, b: %f, c : %f, 판별식 : %f", a, half_b, c, discriminant);
if (discriminant < 0)
return (FALSE);
// 이 시점에서 판별식이 참이 나왔기에 근이 존재한다고 판단한다.
sqrtd = sqrt(discriminant); // 판별식에 루트를 씌움.
root = (-half_b - sqrtd) / a; // 근의 공식 해, 작은 근부터 고려.
// 해당 광선과 교점까지의 거리 사이에 다른 물체가 있거나 너무 멀리 있는 경우를 체크
if (root < rec->tmin || rec->tmax < root)
{
root = (-half_b + sqrtd) / a; // 큰 근 역시 tmin, tmax와의 비교
if (root < rec->tmin || rec->tmax < root) // 큰 근조차 tmin보다 작다면 hit하지 않은 것이므로 FALSE를 반환.
return (FALSE);
}
// 조건문을 통과 == 현재까지 해당 광선이 충돌한 물체 중 가장 가까운 물체임을 의미
rec->t = root; // 광선의 원점과 교점까지의 거리를 rec에 저장한다.
rec->p = ray_at(ray, root); // 교점의 좌표를 rec에 저장한다.
normal = vminus(rec->p, sp->center); // 법선 벡터
printf ("원의 중심 - 교점 -> 법선 벡터 : ");
print_vec(normal);
rec->normal = vdivide(normal, sp->radius);
// 해당 교점의 법선 벡터를 정규화하는 함수.
// 단위 백터를 구하려면 벡터의 각 요소를 벡터의 길이로 나누어주면 된다.
// vunit을 써줄 필요까지 없이 반지름이 곧 벡터의 길이이자 스칼라이므로 반지름으로 나누면 표준벡터가 된다.
printf ("정규화된 법선 벡터 : ");
print_vec(rec->normal);
printf ("표준 벡터 : %f %f\n", vlength(rec->normal), vlength(ray->dir));
set_face_normal(ray, rec); // 카메라가 구의 안쪽에 있을 경우 광선과 법선은 같은 방향을 향하게 된다. 법선과 광선이 반대방향을 향햐도록 확인하는 함수를 추가했다.
return (TRUE);
}
リファレンス
(7)レーシングカーOne Weekend式を理解!4
mini_raytracing_in_c/07.object.md at main · GaepoMorningEagles/mini_raytracing_in_c
Surface Normals and Multiple Objects
Reference
この問題について([minirt]#8オブジェクト構造体), 我々は、より多くの情報をここで見つけました
https://velog.io/@sham/miniRT-8-Object-구조체
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
ray_color.c
//광선이 최종적으로 얻게된 픽셀의 색상 값을 리턴.
t_color3 ray_color(t_ray *ray, t_object *world)
{
t_hit_record rec;
rec.tmin = 0;
rec.tmax = MAX;
if (hit(world, ray, &rec)) // 모든 구조체에 대한 정보를 담은 연결리스트 world로 광선과의 충돌을 테스트한다.
return (vmult(vplus(rec.normal, color3(1, 1, 1)), 0.5));
else
{
// (1-t) * 흰색 + t * 하늘색
return (color3(0.5, 0.5, 0.5));
}
}
hit.c
#include "trace.h"
t_bool hit(t_object *world, t_ray *ray, t_hit_record *rec)
{
t_bool hit_anything;
t_hit_record *temp_rec;
temp_rec = rec;
hit_anything = FALSE;
while (world) // world->next로 훑어가며 등록된 구조체를 전부 체크함
{
if (hit_obj(world, ray, temp_rec))
{
hit_anything = TRUE;
temp_rec->tmax = temp_rec->t;
rec = temp_rec;
}
world = world->next;
}
return (hit_anything);
}
t_bool hit_obj(t_object *world, t_ray *ray, t_hit_record *rec)
{
t_bool hit_result;
hit_result = FALSE;
if (world->type == SP)
hit_result = hit_sphere(world, ray, rec);
return (hit_result);
}
hit_sphere.c
#include "structures.h"
#include "utils.h"
#include "trace.h"
static void print_vec(t_vec3 vec3)
{
printf ("x : %f, y : %f, z : %f\n", vec3.x, vec3.y, vec3.z);
}
t_bool hit_sphere(t_object *world, t_ray *ray, t_hit_record *rec)
{
t_sphere *sp = world->element;
t_vec3 oc; // 0에서부터 벡터로 나타낸 구의 중심.
t_vec3 normal; // 법선 벡터, 표준 벡터가 아니다!
//a, b, c는 각각 t에 관한 근의 공식 2차 방정식의 계수
double a;
double half_b; // b가 half_b로
double c;
double discriminant; // 판별식
double sqrtd;
double root;
oc = vminus(ray->orig, sp->center);
a = vlength2(ray->dir);
half_b = vdot(oc, ray->dir);
c = vlength2(oc) - sp->radius2;
discriminant = half_b * half_b - a * c;
// printf ("a : %f, b: %f, c : %f, 판별식 : %f", a, half_b, c, discriminant);
if (discriminant < 0)
return (FALSE);
// 이 시점에서 판별식이 참이 나왔기에 근이 존재한다고 판단한다.
sqrtd = sqrt(discriminant); // 판별식에 루트를 씌움.
root = (-half_b - sqrtd) / a; // 근의 공식 해, 작은 근부터 고려.
// 해당 광선과 교점까지의 거리 사이에 다른 물체가 있거나 너무 멀리 있는 경우를 체크
if (root < rec->tmin || rec->tmax < root)
{
root = (-half_b + sqrtd) / a; // 큰 근 역시 tmin, tmax와의 비교
if (root < rec->tmin || rec->tmax < root) // 큰 근조차 tmin보다 작다면 hit하지 않은 것이므로 FALSE를 반환.
return (FALSE);
}
// 조건문을 통과 == 현재까지 해당 광선이 충돌한 물체 중 가장 가까운 물체임을 의미
rec->t = root; // 광선의 원점과 교점까지의 거리를 rec에 저장한다.
rec->p = ray_at(ray, root); // 교점의 좌표를 rec에 저장한다.
normal = vminus(rec->p, sp->center); // 법선 벡터
printf ("원의 중심 - 교점 -> 법선 벡터 : ");
print_vec(normal);
rec->normal = vdivide(normal, sp->radius);
// 해당 교점의 법선 벡터를 정규화하는 함수.
// 단위 백터를 구하려면 벡터의 각 요소를 벡터의 길이로 나누어주면 된다.
// vunit을 써줄 필요까지 없이 반지름이 곧 벡터의 길이이자 스칼라이므로 반지름으로 나누면 표준벡터가 된다.
printf ("정규화된 법선 벡터 : ");
print_vec(rec->normal);
printf ("표준 벡터 : %f %f\n", vlength(rec->normal), vlength(ray->dir));
set_face_normal(ray, rec); // 카메라가 구의 안쪽에 있을 경우 광선과 법선은 같은 방향을 향하게 된다. 법선과 광선이 반대방향을 향햐도록 확인하는 함수를 추가했다.
return (TRUE);
}
リファレンス
(7)レーシングカーOne Weekend式を理解!4
mini_raytracing_in_c/07.object.md at main · GaepoMorningEagles/mini_raytracing_in_c
Surface Normals and Multiple Objects
Reference
この問題について([minirt]#8オブジェクト構造体), 我々は、より多くの情報をここで見つけました
https://velog.io/@sham/miniRT-8-Object-구조체
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Reference
この問題について([minirt]#8オブジェクト構造体), 我々は、より多くの情報をここで見つけました https://velog.io/@sham/miniRT-8-Object-구조체テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol