Refactor trace_ray function
This commit is contained in:
parent
bfdea0fd0c
commit
1f5568b63e
@ -46,10 +46,21 @@ typedef struct {
|
|||||||
f32 t2;
|
f32 t2;
|
||||||
} solutions_t;
|
} solutions_t;
|
||||||
|
|
||||||
solutions_t ray_intersects_sphere(vec3f_t origin, vec3f_t direction,
|
typedef struct {
|
||||||
sphere_t sphere);
|
f32 closest_t;
|
||||||
|
sphere_t *closest_sphere;
|
||||||
|
} intersection_t;
|
||||||
|
|
||||||
colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
|
colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
|
||||||
const scene_t *scene, colour_t default_colour);
|
const scene_t *scene, colour_t default_colour);
|
||||||
|
intersection_t find_closest_intersection(vec3f_t origin, vec3f_t direction,
|
||||||
|
f32 t_min, f32 t_max,
|
||||||
|
const scene_t *scene);
|
||||||
|
f32 calculate_lighting_for_intersection(vec3f_t origin, vec3f_t direction,
|
||||||
|
intersection_t intersection,
|
||||||
|
const scene_t *scene);
|
||||||
|
solutions_t ray_intersects_sphere(vec3f_t origin, vec3f_t direction,
|
||||||
|
sphere_t sphere);
|
||||||
f32 compute_lighting(vec3f_t position, vec3f_t surface_normal,
|
f32 compute_lighting(vec3f_t position, vec3f_t surface_normal,
|
||||||
vec3f_t view_vector, f32 specular_exponent,
|
vec3f_t view_vector, f32 specular_exponent,
|
||||||
const scene_t *scene);
|
const scene_t *scene);
|
||||||
@ -167,28 +178,37 @@ i32 main(i32 argc, char *argv[]) {
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
solutions_t ray_intersects_sphere(vec3f_t origin, vec3f_t direction,
|
|
||||||
sphere_t sphere) {
|
|
||||||
f32 r = sphere.radius;
|
|
||||||
vec3f_t CO = vec_sub(vec3f_t, origin, sphere.centre);
|
|
||||||
|
|
||||||
f32 a = vec_dot(vec3f_t, direction, direction);
|
|
||||||
f32 b = 2.0f * vec_dot(vec3f_t, CO, direction);
|
|
||||||
f32 c = vec_dot(vec3f_t, CO, CO) - r * r;
|
|
||||||
|
|
||||||
f32 discriminant = b * b - 4 * a * c;
|
|
||||||
if (discriminant < 0) {
|
|
||||||
return (solutions_t){INFINITY, INFINITY};
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 t1 = (-b + sqrtf(discriminant)) / (2 * a);
|
|
||||||
f32 t2 = (-b - sqrtf(discriminant)) / (2 * a);
|
|
||||||
|
|
||||||
return (solutions_t){t1, t2};
|
|
||||||
}
|
|
||||||
|
|
||||||
colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
|
colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
|
||||||
const scene_t *scene, colour_t default_colour) {
|
const scene_t *scene, colour_t default_colour) {
|
||||||
|
|
||||||
|
intersection_t intersection =
|
||||||
|
find_closest_intersection(origin, direction, t_min, t_max, scene);
|
||||||
|
|
||||||
|
if (!intersection.closest_sphere) {
|
||||||
|
return default_colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 light = calculate_lighting_for_intersection(origin, direction,
|
||||||
|
intersection, scene);
|
||||||
|
|
||||||
|
f32 r = (f32)(intersection.closest_sphere->colour.rgba.r) * light;
|
||||||
|
r = clamp(r, 0.0f, (f32)UINT8_MAX);
|
||||||
|
f32 g = (f32)(intersection.closest_sphere->colour.rgba.g) * light;
|
||||||
|
g = clamp(g, 0.0f, (f32)UINT8_MAX);
|
||||||
|
f32 b = (f32)(intersection.closest_sphere->colour.rgba.b) * light;
|
||||||
|
b = clamp(b, 0.0f, (f32)UINT8_MAX);
|
||||||
|
|
||||||
|
return (colour_t){
|
||||||
|
.rgba.r = (u8)r,
|
||||||
|
.rgba.g = (u8)g,
|
||||||
|
.rgba.b = (u8)b,
|
||||||
|
.rgba.a = intersection.closest_sphere->colour.rgba.a,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
intersection_t find_closest_intersection(vec3f_t origin, vec3f_t direction,
|
||||||
|
f32 t_min, f32 t_max,
|
||||||
|
const scene_t *scene) {
|
||||||
f32 closest_t = INFINITY;
|
f32 closest_t = INFINITY;
|
||||||
sphere_t *closest_sphere = NULL;
|
sphere_t *closest_sphere = NULL;
|
||||||
|
|
||||||
@ -209,35 +229,44 @@ colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!closest_sphere) {
|
return (intersection_t){closest_t, closest_sphere};
|
||||||
return default_colour;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
vec3f_t position =
|
f32 calculate_lighting_for_intersection(vec3f_t origin, vec3f_t direction,
|
||||||
vec_add(vec3f_t, origin, vec_mul_num(vec3f_t, direction, closest_t));
|
intersection_t intersection,
|
||||||
|
const scene_t *scene) {
|
||||||
|
vec3f_t position = vec_add(
|
||||||
|
vec3f_t, origin, vec_mul_num(vec3f_t, direction, intersection.closest_t));
|
||||||
|
|
||||||
vec3f_t surface_normal = vec_sub(vec3f_t, position, closest_sphere->centre);
|
vec3f_t surface_normal =
|
||||||
|
vec_sub(vec3f_t, position, intersection.closest_sphere->centre);
|
||||||
surface_normal = vec_div_num(vec3f_t, surface_normal,
|
surface_normal = vec_div_num(vec3f_t, surface_normal,
|
||||||
vec_magnitude(vec3f_t, surface_normal));
|
vec_magnitude(vec3f_t, surface_normal));
|
||||||
|
|
||||||
vec3f_t view_vector = vec_mul_num(vec3f_t, direction, -1.0f);
|
vec3f_t view_vector = vec_mul_num(vec3f_t, direction, -1.0f);
|
||||||
|
|
||||||
f32 light = compute_lighting(position, surface_normal, view_vector,
|
return compute_lighting(position, surface_normal, view_vector,
|
||||||
closest_sphere->specular, scene);
|
intersection.closest_sphere->specular, scene);
|
||||||
|
}
|
||||||
|
|
||||||
f32 r = (f32)(closest_sphere->colour.rgba.r) * light;
|
solutions_t ray_intersects_sphere(vec3f_t origin, vec3f_t direction,
|
||||||
r = clamp(r, 0.0f, (f32)UINT8_MAX);
|
sphere_t sphere) {
|
||||||
f32 g = (f32)(closest_sphere->colour.rgba.g) * light;
|
f32 r = sphere.radius;
|
||||||
g = clamp(g, 0.0f, (f32)UINT8_MAX);
|
vec3f_t CO = vec_sub(vec3f_t, origin, sphere.centre);
|
||||||
f32 b = (f32)(closest_sphere->colour.rgba.b) * light;
|
|
||||||
b = clamp(b, 0.0f, (f32)UINT8_MAX);
|
|
||||||
|
|
||||||
return (colour_t){
|
f32 a = vec_dot(vec3f_t, direction, direction);
|
||||||
.rgba.r = (u8)r,
|
f32 b = 2.0f * vec_dot(vec3f_t, CO, direction);
|
||||||
.rgba.g = (u8)g,
|
f32 c = vec_dot(vec3f_t, CO, CO) - r * r;
|
||||||
.rgba.b = (u8)b,
|
|
||||||
.rgba.a = closest_sphere->colour.rgba.a,
|
f32 discriminant = b * b - 4 * a * c;
|
||||||
};
|
if (discriminant < 0) {
|
||||||
|
return (solutions_t){INFINITY, INFINITY};
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 t1 = (-b + sqrtf(discriminant)) / (2 * a);
|
||||||
|
f32 t2 = (-b - sqrtf(discriminant)) / (2 * a);
|
||||||
|
|
||||||
|
return (solutions_t){t1, t2};
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 compute_lighting(vec3f_t position, vec3f_t surface_normal,
|
f32 compute_lighting(vec3f_t position, vec3f_t surface_normal,
|
||||||
|
Loading…
Reference in New Issue
Block a user