aboutsummaryrefslogtreecommitdiff
path: root/ray.c
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-02-23 18:30:21 +0100
committerJulian T <julian@jtle.dk>2020-02-23 18:30:21 +0100
commitb0079eaa628a1f2fd99014cd12e6baac17f4d17a (patch)
tree5925033b7d27a7f0263c19b7babc97fbeb700a93 /ray.c
parent9b40029e42f994aeff59ecc44a6d3b8fba93071d (diff)
Added phong light model and fixed sphere intersect
Diffstat (limited to 'ray.c')
-rw-r--r--ray.c82
1 files changed, 66 insertions, 16 deletions
diff --git a/ray.c b/ray.c
index 0e82546..d5b6a89 100644
--- a/ray.c
+++ b/ray.c
@@ -4,6 +4,8 @@
#include "ray.h"
+extern int print;
+
// https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection
// http://viclw17.github.io/2018/07/16/raytracing-ray-sphere-intersection/
// https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
@@ -26,6 +28,9 @@ COORD_T ray_intersect_sphere(sphere_t *s, ray_t *ray, bool skip_dist)
return -1;
}
if (skip_dist) {
+ if (print) {
+ printf("sph dist: skip\n");
+ }
return 1;
}
@@ -34,11 +39,11 @@ COORD_T ray_intersect_sphere(sphere_t *s, ray_t *ray, bool skip_dist)
-0.5 * (b + sqrt(d)) :
-0.5 * (b - sqrt(d));
- COORD_T x0 = q / a;
- COORD_T x1 = c / q;
+ COORD_T x1 = q / a;
+ COORD_T x0 = c / q;
// Take the correct result. If one is zero take the other.
- if (x0 <= 0) {
+ if (x0 <= ZERO_APROX) {
if (x1 <= 0) {
return -1;
}
@@ -47,9 +52,12 @@ COORD_T ray_intersect_sphere(sphere_t *s, ray_t *ray, bool skip_dist)
}
// If point is on sphere it will be zero close to zero
- if (x0 < 1e-3) {
+ if (x0 < ZERO_APROX) {
return -1;
}
+ if (print) {
+ printf("sph dist: %f\n", x0);
+ }
return x0;
}
@@ -60,12 +68,18 @@ COORD_T ray_intersect_plane(plane_t *p, ray_t *ray, bool skip_dist)
{
// If zero ray is parralel to plane
COORD_T nr = vector_dot(p->norm, ray->direction);
- //
+
// Take care of rounding errors
if (nr < ZERO_APROX && nr > -ZERO_APROX) {
+ if (print) {
+ printf("Ohh no");
+ }
return -1;
}
if (skip_dist) {
+ if (print) {
+ printf("pdist: skip\n");
+ }
return 1;
}
@@ -75,6 +89,9 @@ COORD_T ray_intersect_plane(plane_t *p, ray_t *ray, bool skip_dist)
vector_sub(&tmp, &tmp, ray->start);
COORD_T t = vector_dot(&tmp, p->norm) / nr;
+ if (print) {
+ printf("pdist: %f\n", t);
+ }
return t;
}
@@ -102,7 +119,10 @@ object_t *ray_cast(space_t *s, ray_t *r, COORD_T *dist_ret, bool chk, COORD_T ch
while (o) {
COORD_T d = ray_intersect(o, r, false);
- if (d > 0) {
+ if (print)
+ printf("Distance: %f\n", d);
+
+ if (d > ZERO_APROX) {
if (chk && chk_dist > d) {
if (dist_ret) {
*dist_ret = d;
@@ -143,16 +163,23 @@ color_t *ray_trace(space_t *s, unsigned int x, unsigned int y)
return NULL;
}
- // Calculate new ray point
r.start = vector_scale(NULL, r.direction, dist);
vector_add(r.start, r.start, &s->view.position);
// Calculate normal vector
vector_t n;
obj_norm_at(o, &n, r.start);
+
+ // And vector towards viewer
+ //printf("point: "); vector_print(r.start);
+ vector_t V;
+ vector_sub(&V, &s->view.position, r.start);
+ // Normalice it
+ vector_scale_inv(&V, &V, vector_len(&V));
+ //printf("V: "); vector_print(&V);
// Hit color
- color_t *c = color_set(NULL, 0, 0, 0);
+ color_t *c = color_set(NULL, s->ambient.r, s->ambient.g, s->ambient.b);
// Cast light rays
light_t *light = s->lights;
@@ -162,26 +189,49 @@ color_t *ray_trace(space_t *s, unsigned int x, unsigned int y)
vector_sub(&l, light->pos, r.start);
COORD_T d = vector_len(&l);
+ vector_scale_inv(&l, &l, vector_len(&l));
+
// Find obstacles
+ if (print) printf("Starting\n");
r.direction = &l;
object_t *obs = ray_cast(s, &r, NULL, true, d);
if (obs) {
+ if (print)
+ printf("Light ray hit\n");
+
light = light->next;
continue;
}
+ if (print)
+ printf("Light ray went through\n");
- // Calculate unit
- vector_scale_inv(&l, &l, vector_len(&l));
+ // Calculate Deffuse part
color_t tmp;
- color_scale(&tmp, light->defuse, vector_dot(&l, &n));
- color_add(c, &tmp, c);
-
+ COORD_T cl = vector_dot(&l, &n);
+ if (cl > 0) {
+ color_scale(&tmp, light->defuse, cl * o->m->defuse);
+ color_add(c, &tmp, c);
+ }
+
+ // calculate specular part. TODO implement blinn-phong
+ // Calculate R_m
+ vector_t R;
+ vector_scale(&R, &n, 2 * vector_dot(&l, &n));
+ vector_sub(&R, &R, &l);
+ //printf("R: ");vector_print(&R);
+
+ // Add it to the light
+ cl = 1 * vector_dot(&R, &V);
+ if (cl > 0) {
+ cl = pow(cl, o->m->shine);
+ color_scale(&tmp, light->specular, cl * o->m->specular);
+ color_add(c, &tmp, c);
+ }
+
light = light->next;
}
- if (o->m) {
- color_scale_vector(c, c, &o->m->color);
- }
+ color_scale_vector(c, c, &o->m->color);
return c;
}