diff options
-rw-r--r-- | main.c | 17 | ||||
-rw-r--r-- | ray.c | 54 | ||||
-rw-r--r-- | scene.c | 7 | ||||
-rw-r--r-- | scene.h | 17 | ||||
-rw-r--r-- | test.png | bin | 70902 -> 47594 bytes |
5 files changed, 69 insertions, 26 deletions
@@ -23,24 +23,18 @@ int main() material_t m; vector_set(&m.color, 1, 1, 1); - m.defuse = 0.0; - m.specular = 0.0; - m.shine = 40; + material_set_phong(&m, 0, 0, 40); m.reflective = 0.5; material_t m2; vector_set(&m2.color, 0.1, 1, 0.7); - m2.defuse = 1; - m2.specular = 0.7; - m2.shine = 10; + material_set_phong(&m2, 1, 0.7, 10); 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.0; - mpl.shine = 50; + material_set_phong(&mpl, 1, 0.0, 50); mpl.reflective = 0.0; vector_set(&s.view.position, 0, 14, 8); @@ -54,8 +48,9 @@ int main() 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_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_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, 20, 0, 30), 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); @@ -129,7 +129,9 @@ 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 *N, vector_t *eye, vector_t *point) +// Calculates the phong lightning at point from position eye. +// N is the normal vector at object o +static void light_phong(space_t *s, color_t *dest, object_t *o, vector_t *N, vector_t *eye, vector_t *point) { ray_t r; r.start = point; @@ -142,8 +144,7 @@ static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *N, vector_scale_inv(&V, &V, vector_len(&V)); // Cast light rays - light_t *light = s->lights; - while (light) { + for (light_t *light = s->lights; light; light = light->next) { vector_t l; // Calculate distance to light @@ -157,7 +158,6 @@ static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *N, r.direction = &l; object_t *obs = ray_cast(s, &r, NULL, true, d); if (obs) { - light = light->next; continue; } @@ -165,7 +165,7 @@ static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *N, color_t tmp; COORD_T cl = vector_dot(&l, N); if (cl > 0) { - color_scale(&tmp, light->defuse, cl * o->m->defuse); + color_scale(&tmp, light->defuse, cl * o->m->phong.defuse); color_add(dest, &tmp, dest); } @@ -178,12 +178,40 @@ static void ray_calc_light(space_t *s, color_t *dest, object_t *o, vector_t *N, // 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); + cl = pow(cl, o->m->phong.shine); + color_scale(&tmp, light->specular, cl * o->m->phong.specular); color_add(dest, &tmp, dest); } - light = light->next; + } +} + +static void light_lambert(space_t *s, color_t *dest, object_t *o, vector_t *N, vector_t *eye, vector_t *point) +{ + vector_t l; + ray_t r = {start: point, direction: &l}; + + for (light_t *light = s->lights; light; light = light->next) { + // Calculate direction of lights + vector_sub(&l, light->post, point); + COORD_T d = vector_len(&l); + + // Normalize + vector_scale_inv(&l, &l, vector_len(&l)); + + // Find obstracles + object_t *obj = ray_cast(s, &r, NULL, true, d); + if (obj) { + continue; + } + + // Calculate lambert stuff + COORD_T cl = vector_dot(&l, N); + if (cl > 0) { + color_scale(&tmp, light->defuse, cl * o->m->phong.defuse); + color_add(dest, &tmp, dest); + } + ` } } @@ -202,17 +230,19 @@ int ray_trace_recur(space_t *s, color_t *dest, ray_t *ray, unsigned hop, COORD_T vector_t rdir, rstart; ray_t r = {start: &rstart, direction: &rdir}; + // Calculate hit point vector_scale(r.start, ray->direction, dist); vector_add(r.start, r.start, ray->start); - // Calculate normal vector + // Calculate normal vector at object 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); + switch (o->m->light_type) { + case LIGHT_PHONG: + light_phong(s, &c, o, &N, ray->start, r.start); + } // Calculate reflection vector @@ -60,6 +60,13 @@ light_t *add_light(space_t *s, vector_t *pos, color_t *defuse, color_t *specular return o; } +void material_set_phong(material_t *m, COORD_T defuse, COORD_T specular, unsigned int shine) { + m->light_type = LIGHT_PHONG; + m->phong.defuse = defuse; + m->phong.specular = specular; + m->phong.shine = shine; +} + void obj_norm_at(object_t *o, vector_t *dest, vector_t *point) { switch(o->type) { @@ -11,6 +11,10 @@ #define TYPE_SPHERE 1 #define TYPE_PLANE 2 +#define LIGHT_LAMBERT 0 +#define LIGHT_PHONG 1 +#define LIGHT_NONE 2 + typedef struct { vector_t *center; COORD_T radius; @@ -33,9 +37,14 @@ typedef struct { vector_t color; // Light properties - COORD_T defuse; - COORD_T specular; - unsigned int shine; + unsigned int light_type; + union { + struct phong_s { + COORD_T defuse; + COORD_T specular; + unsigned int shine; + } phong; + }; // Reflective properties COORD_T reflective; @@ -68,6 +77,8 @@ object_t *add_sphere(space_t *s, vector_t *c, COORD_T r, material_t *m); object_t *add_plane(space_t *s, vector_t *start, vector_t *dir, material_t *m); light_t *add_light(space_t *s, vector_t *pos, color_t *defuse, color_t *specular); +void material_set_phong(material_t *m, COORD_T defuse, COORD_T specular, unsigned int shine); + void obj_norm_at(object_t *o, vector_t *dest, vector_t *point); #endif Binary files differ |