Add an empty Cornell box
This commit is contained in:
parent
baa67b51db
commit
990b9d3016
112
hittable.c
112
hittable.c
@ -133,6 +133,34 @@ Hittable *hittable_create_xy_rectangle(double x0, double x1, double y0,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hittable *hittable_create_xz_rectangle(double x0, double x1, double z0,
|
||||||
|
double z1, double k,
|
||||||
|
const Material *material, Arena *arena) {
|
||||||
|
Hittable *result = arena_alloc(arena, sizeof(Hittable));
|
||||||
|
result->type = HITTABLE_XZ_RECTANGLE;
|
||||||
|
result->xz_rectangle.x0 = x0;
|
||||||
|
result->xz_rectangle.x1 = x1;
|
||||||
|
result->xz_rectangle.z0 = z0;
|
||||||
|
result->xz_rectangle.z1 = z1;
|
||||||
|
result->xz_rectangle.k = k;
|
||||||
|
result->xz_rectangle.material = material;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hittable *hittable_create_yz_rectangle(double y0, double y1, double z0,
|
||||||
|
double z1, double k,
|
||||||
|
const Material *material, Arena *arena) {
|
||||||
|
Hittable *result = arena_alloc(arena, sizeof(Hittable));
|
||||||
|
result->type = HITTABLE_YZ_RECTANGLE;
|
||||||
|
result->yz_rectangle.y0 = y0;
|
||||||
|
result->yz_rectangle.y1 = y1;
|
||||||
|
result->yz_rectangle.z0 = z0;
|
||||||
|
result->yz_rectangle.z1 = z1;
|
||||||
|
result->yz_rectangle.k = k;
|
||||||
|
result->yz_rectangle.material = material;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static bool hittable_list_hit(const HittableList *list, Ray r, double t_min,
|
static bool hittable_list_hit(const HittableList *list, Ray r, double t_min,
|
||||||
double t_max, HitRecord *record) {
|
double t_max, HitRecord *record) {
|
||||||
bool hit_anything = false;
|
bool hit_anything = false;
|
||||||
@ -251,6 +279,56 @@ static bool xy_rectangle_hit(const XYRectangle *rectangle, Ray r, double t_min,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool xz_rectangle_hit(const XZRectangle *rectangle, Ray r, double t_min,
|
||||||
|
double t_max, HitRecord *record) {
|
||||||
|
double t = (rectangle->k - r.origin.y) / r.direction.y;
|
||||||
|
if (t < t_min || t > t_max)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
double x = r.origin.x + t * r.direction.x;
|
||||||
|
double z = r.origin.z + t * r.direction.z;
|
||||||
|
|
||||||
|
if (x < rectangle->x0 || x > rectangle->x1 || z < rectangle->z0 ||
|
||||||
|
z > rectangle->z1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
record->u = (x - rectangle->x0) / (rectangle->x1 - rectangle->x0);
|
||||||
|
record->v = (z - rectangle->z0) / (rectangle->z1 - rectangle->z0);
|
||||||
|
record->t = t;
|
||||||
|
|
||||||
|
Vec3 outward_normal = {0.0, 1.0, 0.0};
|
||||||
|
hit_record_set_face_normal(record, r, outward_normal);
|
||||||
|
record->material = rectangle->material;
|
||||||
|
record->p = ray_at(r, t);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool yz_rectangle_hit(const YZRectangle *rectangle, Ray r, double t_min,
|
||||||
|
double t_max, HitRecord *record) {
|
||||||
|
double t = (rectangle->k - r.origin.x) / r.direction.x;
|
||||||
|
if (t < t_min || t > t_max)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
double y = r.origin.y + t * r.direction.y;
|
||||||
|
double z = r.origin.z + t * r.direction.z;
|
||||||
|
|
||||||
|
if (y < rectangle->y0 || y > rectangle->y1 || z < rectangle->z0 ||
|
||||||
|
z > rectangle->z1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
record->u = (y - rectangle->y0) / (rectangle->y1 - rectangle->y0);
|
||||||
|
record->v = (z - rectangle->z0) / (rectangle->z1 - rectangle->z0);
|
||||||
|
record->t = t;
|
||||||
|
|
||||||
|
Vec3 outward_normal = {1.0, 0.0, 0.0};
|
||||||
|
hit_record_set_face_normal(record, r, outward_normal);
|
||||||
|
record->material = rectangle->material;
|
||||||
|
record->p = ray_at(r, t);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max,
|
bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max,
|
||||||
HitRecord *record) {
|
HitRecord *record) {
|
||||||
switch (hittable->type) {
|
switch (hittable->type) {
|
||||||
@ -264,6 +342,10 @@ bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max,
|
|||||||
return bvh_node_hit(&hittable->bvh_node, r, t_min, t_max, record);
|
return bvh_node_hit(&hittable->bvh_node, r, t_min, t_max, record);
|
||||||
case HITTABLE_XY_RECTANGLE:
|
case HITTABLE_XY_RECTANGLE:
|
||||||
return xy_rectangle_hit(&hittable->xy_rectangle, r, t_min, t_max, record);
|
return xy_rectangle_hit(&hittable->xy_rectangle, r, t_min, t_max, record);
|
||||||
|
case HITTABLE_XZ_RECTANGLE:
|
||||||
|
return xz_rectangle_hit(&hittable->xz_rectangle, r, t_min, t_max, record);
|
||||||
|
case HITTABLE_YZ_RECTANGLE:
|
||||||
|
return yz_rectangle_hit(&hittable->yz_rectangle, r, t_min, t_max, record);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -325,8 +407,8 @@ static bool bvh_node_bounding_box(const BVHNode *node, AABB *bounding_box) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xy_rectangle_bouding_box(const XYRectangle *rectangle,
|
static bool xy_rectangle_bounding_box(const XYRectangle *rectangle,
|
||||||
AABB *bounding_box) {
|
AABB *bounding_box) {
|
||||||
/* Pad the bounding box to make sure it is not zero-width */
|
/* Pad the bounding box to make sure it is not zero-width */
|
||||||
*bounding_box = (AABB){
|
*bounding_box = (AABB){
|
||||||
.min = {rectangle->x0, rectangle->y0, rectangle->k - 0.0001},
|
.min = {rectangle->x0, rectangle->y0, rectangle->k - 0.0001},
|
||||||
@ -335,6 +417,26 @@ static bool xy_rectangle_bouding_box(const XYRectangle *rectangle,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool xz_rectangle_bounding_box(const XZRectangle *rectangle,
|
||||||
|
AABB *bounding_box) {
|
||||||
|
/* Pad the bounding box to make sure it is not zero-width */
|
||||||
|
*bounding_box = (AABB){
|
||||||
|
.min = {rectangle->x0, rectangle->k - 0.0001, rectangle->z0},
|
||||||
|
.max = {rectangle->x1, rectangle->k + 0.0001, rectangle->z1},
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool yz_rectangle_bounding_box(const YZRectangle *rectangle,
|
||||||
|
AABB *bounding_box) {
|
||||||
|
/* Pad the bounding box to make sure it is not zero-width */
|
||||||
|
*bounding_box = (AABB){
|
||||||
|
.min = {rectangle->k - 0.0001, rectangle->y0, rectangle->z0},
|
||||||
|
.max = {rectangle->k + 0.0001, rectangle->y1, rectangle->z1},
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool hittable_bounding_box(const Hittable *hittable, double time_start,
|
bool hittable_bounding_box(const Hittable *hittable, double time_start,
|
||||||
double time_end, AABB *bounding_box) {
|
double time_end, AABB *bounding_box) {
|
||||||
switch (hittable->type) {
|
switch (hittable->type) {
|
||||||
@ -349,7 +451,11 @@ bool hittable_bounding_box(const Hittable *hittable, double time_start,
|
|||||||
case HITTABLE_BVH_NODE:
|
case HITTABLE_BVH_NODE:
|
||||||
return bvh_node_bounding_box(&hittable->bvh_node, bounding_box);
|
return bvh_node_bounding_box(&hittable->bvh_node, bounding_box);
|
||||||
case HITTABLE_XY_RECTANGLE:
|
case HITTABLE_XY_RECTANGLE:
|
||||||
return xy_rectangle_bouding_box(&hittable->xy_rectangle, bounding_box);
|
return xy_rectangle_bounding_box(&hittable->xy_rectangle, bounding_box);
|
||||||
|
case HITTABLE_XZ_RECTANGLE:
|
||||||
|
return xz_rectangle_bounding_box(&hittable->xz_rectangle, bounding_box);
|
||||||
|
case HITTABLE_YZ_RECTANGLE:
|
||||||
|
return yz_rectangle_bounding_box(&hittable->yz_rectangle, bounding_box);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
20
hittable.h
20
hittable.h
@ -28,6 +28,8 @@ typedef enum HittableType {
|
|||||||
HITTABLE_MOVING_SPHERE,
|
HITTABLE_MOVING_SPHERE,
|
||||||
HITTABLE_BVH_NODE,
|
HITTABLE_BVH_NODE,
|
||||||
HITTABLE_XY_RECTANGLE,
|
HITTABLE_XY_RECTANGLE,
|
||||||
|
HITTABLE_XZ_RECTANGLE,
|
||||||
|
HITTABLE_YZ_RECTANGLE,
|
||||||
} HittableType;
|
} HittableType;
|
||||||
|
|
||||||
typedef struct Hittable Hittable;
|
typedef struct Hittable Hittable;
|
||||||
@ -62,6 +64,16 @@ typedef struct XYRectangle {
|
|||||||
double x0, x1, y0, y1, k;
|
double x0, x1, y0, y1, k;
|
||||||
} XYRectangle;
|
} XYRectangle;
|
||||||
|
|
||||||
|
typedef struct XZRectangle {
|
||||||
|
const Material *material;
|
||||||
|
double x0, x1, z0, z1, k;
|
||||||
|
} XZRectangle;
|
||||||
|
|
||||||
|
typedef struct YZRectangle {
|
||||||
|
const Material *material;
|
||||||
|
double y0, y1, z0, z1, k;
|
||||||
|
} YZRectangle;
|
||||||
|
|
||||||
struct Hittable {
|
struct Hittable {
|
||||||
HittableType type;
|
HittableType type;
|
||||||
union {
|
union {
|
||||||
@ -70,6 +82,8 @@ struct Hittable {
|
|||||||
MovingSphere moving_sphere;
|
MovingSphere moving_sphere;
|
||||||
BVHNode bvh_node;
|
BVHNode bvh_node;
|
||||||
XYRectangle xy_rectangle;
|
XYRectangle xy_rectangle;
|
||||||
|
XZRectangle xz_rectangle;
|
||||||
|
YZRectangle yz_rectangle;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,6 +99,12 @@ Hittable *hittable_create_bvh_node(const Hittable **objects, size_t start,
|
|||||||
Hittable *hittable_create_xy_rectangle(double x0, double x1, double y0,
|
Hittable *hittable_create_xy_rectangle(double x0, double x1, double y0,
|
||||||
double y1, double k,
|
double y1, double k,
|
||||||
const Material *material, Arena *arena);
|
const Material *material, Arena *arena);
|
||||||
|
Hittable *hittable_create_xz_rectangle(double x0, double x1, double z0,
|
||||||
|
double z1, double k,
|
||||||
|
const Material *material, Arena *arena);
|
||||||
|
Hittable *hittable_create_yz_rectangle(double y0, double y1, double z0,
|
||||||
|
double z1, double k,
|
||||||
|
const Material *material, Arena *arena);
|
||||||
|
|
||||||
bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max,
|
bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max,
|
||||||
HitRecord *record);
|
HitRecord *record);
|
||||||
|
|||||||
57
main.c
57
main.c
@ -22,9 +22,10 @@
|
|||||||
#define SCENE_TWO_PERLIN_SPHERES 2
|
#define SCENE_TWO_PERLIN_SPHERES 2
|
||||||
#define SCENE_EARTH 3
|
#define SCENE_EARTH 3
|
||||||
#define SCENE_SIMPLE_LIGHT 4
|
#define SCENE_SIMPLE_LIGHT 4
|
||||||
|
#define SCENE_CORNELL_BOX 5
|
||||||
|
|
||||||
#ifndef SCENE_SELECT
|
#ifndef SCENE_SELECT
|
||||||
#define SCENE_SELECT SCENE_SIMPLE_LIGHT
|
#define SCENE_SELECT SCENE_CORNELL_BOX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Color ray_color(Ray r, Color background_color, const Hittable *world,
|
static Color ray_color(Ray r, Color background_color, const Hittable *world,
|
||||||
@ -186,6 +187,41 @@ static Hittable *simple_light(Arena *arena) {
|
|||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Hittable *cornell_box(Arena *arena) {
|
||||||
|
Hittable *world = hittable_create_hittable_list(arena);
|
||||||
|
|
||||||
|
Material *red =
|
||||||
|
material_create_lambertian_color((Color){0.65, 0.05, 0.05}, arena);
|
||||||
|
Material *white =
|
||||||
|
material_create_lambertian_color((Color){0.73, 0.73, 0.73}, arena);
|
||||||
|
Material *green =
|
||||||
|
material_create_lambertian_color((Color){0.12, 0.45, 0.15}, arena);
|
||||||
|
Material *light =
|
||||||
|
material_create_diffuse_light_color((Color){15.0, 15.0, 15.0}, arena);
|
||||||
|
|
||||||
|
hittable_list_add(
|
||||||
|
&world->list,
|
||||||
|
hittable_create_yz_rectangle(0, 555, 0, 555, 555, green, arena), arena);
|
||||||
|
hittable_list_add(&world->list,
|
||||||
|
hittable_create_yz_rectangle(0, 555, 0, 555, 0, red, arena),
|
||||||
|
arena);
|
||||||
|
hittable_list_add(
|
||||||
|
&world->list,
|
||||||
|
hittable_create_xz_rectangle(213, 343, 227, 332, 554, light, arena),
|
||||||
|
arena);
|
||||||
|
hittable_list_add(
|
||||||
|
&world->list,
|
||||||
|
hittable_create_xz_rectangle(0, 555, 0, 555, 0, white, arena), arena);
|
||||||
|
hittable_list_add(
|
||||||
|
&world->list,
|
||||||
|
hittable_create_xz_rectangle(0, 555, 0, 555, 555, white, arena), arena);
|
||||||
|
hittable_list_add(
|
||||||
|
&world->list,
|
||||||
|
hittable_create_xy_rectangle(0, 555, 0, 555, 555, white, arena), arena);
|
||||||
|
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
srand(time(0));
|
srand(time(0));
|
||||||
|
|
||||||
@ -212,10 +248,9 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
/* Image parameters */
|
/* Image parameters */
|
||||||
|
|
||||||
const double aspect_ratio = 16.0 / 9.0;
|
double aspect_ratio = 16.0 / 9.0;
|
||||||
const int image_width = 400;
|
int image_width = 400;
|
||||||
const int image_height = (int)(image_width / aspect_ratio);
|
int samples_per_pixel = 400;
|
||||||
const int samples_per_pixel = 400;
|
|
||||||
const int max_depth = 50;
|
const int max_depth = 50;
|
||||||
|
|
||||||
Point3 look_from = {0.0, 0.0, 1.0};
|
Point3 look_from = {0.0, 0.0, 1.0};
|
||||||
@ -260,8 +295,20 @@ int main(int argc, char *argv[]) {
|
|||||||
look_from = (Point3){26.0, 3.0, 6.0};
|
look_from = (Point3){26.0, 3.0, 6.0};
|
||||||
look_at = (Point3){0.0, 2.0, 0.0};
|
look_at = (Point3){0.0, 2.0, 0.0};
|
||||||
vfov = 20.0;
|
vfov = 20.0;
|
||||||
|
#elif SCENE_SELECT == SCENE_CORNELL_BOX
|
||||||
|
world = cornell_box(&arena);
|
||||||
|
aspect_ratio = 1.0;
|
||||||
|
image_width = 600;
|
||||||
|
samples_per_pixel = 200;
|
||||||
|
background_color = (Color){0.0, 0.0, 0.0};
|
||||||
|
look_from = (Point3){278.0, 278.0, -800.0};
|
||||||
|
look_at = (Point3){278.0, 278.0, 0.0};
|
||||||
|
vfov = 40.0;
|
||||||
|
#else
|
||||||
|
#error Unknown scene selected
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int image_height = (int)(image_width / aspect_ratio);
|
||||||
Vec3 up = {0.0, 1.0, 0.0};
|
Vec3 up = {0.0, 1.0, 0.0};
|
||||||
|
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user