aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c17
-rw-r--r--ray.c54
-rw-r--r--scene.c7
-rw-r--r--scene.h17
-rw-r--r--test.pngbin70902 -> 47594 bytes
5 files changed, 69 insertions, 26 deletions
diff --git a/main.c b/main.c
index 508efa7..f1b49e7 100644
--- a/main.c
+++ b/main.c
@@ -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);
diff --git a/ray.c b/ray.c
index 9d18bdb..f81b672 100644
--- a/ray.c
+++ b/ray.c
@@ -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
diff --git a/scene.c b/scene.c
index 5a41041..fd3881c 100644
--- a/scene.c
+++ b/scene.c
@@ -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) {
diff --git a/scene.h b/scene.h
index 90e5ebb..c2893ca 100644
--- a/scene.h
+++ b/scene.h
@@ -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
diff --git a/test.png b/test.png
index 942cae7..c9da89a 100644
--- a/test.png
+++ b/test.png
Binary files differ