aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-02-23 22:34:43 +0100
committerJulian T <julian@jtle.dk>2020-02-23 22:34:43 +0100
commitaa6bcd1c813a17d57083d79c4b27a65eccd960ce (patch)
tree6e5e84898493350769f6afa03c1bcc44c6086163
parentf2386856f2739df397617b92edd52cfc687bb14b (diff)
Added reflections
-rw-r--r--main.c35
-rw-r--r--ray.c75
-rw-r--r--scene.h4
-rw-r--r--viewpoint.h4
4 files changed, 82 insertions, 36 deletions
diff --git a/main.c b/main.c
index f0d495a..e86a995 100644
--- a/main.c
+++ b/main.c
@@ -10,7 +10,7 @@
#define TESTW 1000
#define TESTH 1000
-color_t back = {0, 0, 0};
+color_t back = {255, 255, 255};
int print = 0;
int main()
@@ -19,22 +19,31 @@ int main()
space_t s;
s.objects = NULL;
s.lights = NULL;
- color_set(&s.ambient, 30, 30, 30);
+ color_set(&s.ambient, 25, 25, 25);
material_t m;
- vector_set(&m.color, 0, 1, 0);
- m.defuse = 1;
- m.specular = 0.3;
- m.shine = 20;
+ vector_set(&m.color, 1, 1, 1);
+ m.defuse = 0.0;
+ m.specular = 0.0;
+ m.shine = 40;
+ m.reflective = 0.5;
+
+ material_t m2;
+ vector_set(&m2.color, 0.1, 1, 0.7);
+ m2.defuse = 1;
+ m2.specular = 0.0;
+ m2.shine = 40;
+ m2.reflective = 0.0;
material_t mpl;
//vector_set(&mpl.color, 0, 0.396, 0.7019);
vector_set(&mpl.color, 1, 1, 1);
mpl.defuse = 1;
- mpl.specular = 0.3;
- mpl.shine = 20;
+ mpl.specular = 0.0;
+ mpl.shine = 50;
+ mpl.reflective = 0;
- vector_set(&s.view.position, 0, 15, 8);
+ vector_set(&s.view.position, 0, 14, 8);
vector_set(&s.view.target, 0, 0, 0);
s.view.width = TESTW;
s.view.height = TESTH;
@@ -42,11 +51,11 @@ int main()
viewpoint_init(&s.view);
// Setup plane
- add_sphere(&s, vector_set(NULL, 3, 0, 5), 5, &m);
- add_sphere(&s, vector_set(NULL, -6, -3, 7), 3, &m);
- //add_sphere(&s, vector_set(NULL, 10, 0, 5), 5);
+ add_sphere(&s, vector_set(NULL, 3, -1, 5), 5, &m);
+ add_sphere(&s, vector_set(NULL, 3, 7, 3), 2, &m2);
add_plane(&s, vector_set(NULL, 0, 0, 2), vector_set(NULL, 0, 0, 1), &mpl);
- add_light(&s, vector_set(NULL, 10, 0, 20), color_set(NULL, 255, 255, 255), color_set(NULL, 150, 150, 150));
+ add_plane(&s, vector_set(NULL, 0, -20, 0), vector_set(NULL, 0, 1, 0), &mpl);
+ add_light(&s, vector_set(NULL, 20, 0, 20), color_set(NULL, 255, 255, 255), color_set(NULL, 150, 150, 150));
//add_light(&s, vector_set(NULL, 0, 10, 20), color_set(NULL, 255, 255, 255), color_set(NULL, 150, 150, 150));
pgm_write_header(stdout, TESTW, TESTH);
diff --git a/ray.c b/ray.c
index 3eef341..b7f8608 100644
--- a/ray.c
+++ b/ray.c
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <math.h>
+#include <stdlib.h>
#include "vector.h"
#include "ray.h"
@@ -148,14 +149,10 @@ object_t *ray_cast(space_t *s, ray_t *r, COORD_T *dist_ret, bool chk, COORD_T ch
return smallest;
}
-static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *eye, vector_t *point)
+static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *N, vector_t *eye, vector_t *point)
{
ray_t r;
r.start = point;
-
- // Calculate normal vector
- vector_t N;
- obj_norm_at(o, &N, point);
// And vector towards viewer
vector_t V;
@@ -186,7 +183,7 @@ static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *eye
// Calculate Deffuse part
color_t tmp;
- COORD_T cl = vector_dot(&l, &N);
+ COORD_T cl = vector_dot(&l, N);
if (cl > 0) {
color_scale(&tmp, light->defuse, cl * o->m->defuse);
color_add(dest, &tmp, dest);
@@ -195,7 +192,7 @@ static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *eye
// calculate specular part. TODO implement blinn-phong
// Calculate R_m
vector_t R;
- vector_scale(&R, &N, 2 * vector_dot(&l, &N));
+ vector_scale(&R, N, 2 * vector_dot(&l, N));
vector_sub(&R, &R, &l);
// Add it to the light
@@ -210,6 +207,49 @@ static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *eye
}
}
+int ray_trace_recur(space_t *s, color_t *dest, ray_t *ray, unsigned hop, COORD_T scale)
+{
+ COORD_T dist;
+ color_t c;
+ color_set(&c, 0, 0, 0);
+
+ object_t *o = ray_cast(s, ray, &dist, false, 0);
+ if (!o) {
+ return 1;
+ }
+
+ vector_t rdir, rstart;
+ ray_t r = {start: &rstart, direction: &rdir};
+
+ vector_scale(r.start, ray->direction, dist);
+ vector_add(r.start, r.start, ray->start);
+
+ // Calculate normal vector
+ vector_t N;
+ obj_norm_at(o, &N, r.start);
+
+ // Check if we should calculate light
+ if (o->m->defuse + o->m->specular > ZERO_APROX) {
+ // Add all light hitting o at r.start to c
+ ray_calc_light(s, &c, o, &N, ray->start, r.start);
+ }
+
+ // Calculate reflection vector
+ if (hop < 2 && o->m->reflective > ZERO_APROX) {
+ vector_scale(r.direction, &N, 2 * vector_dot(ray->direction, &N));
+ vector_sub(r.direction, ray->direction, r.direction);
+
+ ray_trace_recur(s, &c, &r, hop+1, o->m->reflective);
+ }
+
+ // Scale by the objects own color.
+ color_scale_vector(&c, &c, &o->m->color);
+ color_scale(&c, &c, scale);
+ color_add(dest, dest, &c);
+
+ return 0;
+}
+
color_t *ray_trace(space_t *s, unsigned int x, unsigned int y)
{
// Setup primary ray
@@ -218,22 +258,15 @@ color_t *ray_trace(space_t *s, unsigned int x, unsigned int y)
r.direction = vector_copy(NULL, NULL);
viewpoint_ray(&s->view, r.direction, x, y);
- // Cast it
- COORD_T dist;
- object_t *o = ray_cast(s, &r, &dist, false, 0);
- if (!o) {
- return NULL;
- }
-
- r.start = vector_scale(NULL, r.direction, dist);
- vector_add(r.start, r.start, &s->view.position);
-
- // Hit color
+ // Init return color. Will be accumilated with all the detected light.
color_t *c = color_set(NULL, s->ambient.r, s->ambient.g, s->ambient.b);
- ray_calc_light(s, c, o, &s->view.position, r.start);
-
- color_scale_vector(c, c, &o->m->color);
+ // Run the recursive ray trace
+ int status = ray_trace_recur(s, c, &r, 0, 1);
+ if (status) {
+ free(c);
+ return NULL;
+ }
return c;
}
diff --git a/scene.h b/scene.h
index 489aece..5e647eb 100644
--- a/scene.h
+++ b/scene.h
@@ -32,9 +32,13 @@ typedef struct light_s{
typedef struct {
vector_t color;
+ // Light properties
COORD_T defuse;
COORD_T specular;
unsigned int shine;
+
+ // Reflective properties
+ COORD_T reflective;
} material_t;
// General object structure
diff --git a/viewpoint.h b/viewpoint.h
index 0aae5db..6e5178c 100644
--- a/viewpoint.h
+++ b/viewpoint.h
@@ -3,8 +3,8 @@
#include "vector.h"
-// 90 degrees
-#define FOV 3.1415/2
+// 100 degrees
+#define FOV 1.74533
typedef struct {
// Viewpoint dimensions