aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-05-07 09:46:56 +0200
committerJulian T <julian@jtle.dk>2020-05-07 09:46:56 +0200
commitba99860760eda6ec221b15190547736407723f84 (patch)
tree18aa0f770efd4d584ea44709c16c78ea82d3ec3f
parentc2bd065bafe52a3e85be7a87945ed47aec7a33d9 (diff)
Global illumination
-rw-r--r--Makefile2
-rw-r--r--ctranslate.c20
-rw-r--r--main.c23
-rw-r--r--ray.c79
-rw-r--r--scene.h1
-rw-r--r--vector.c11
-rw-r--r--vector.h1
7 files changed, 99 insertions, 38 deletions
diff --git a/Makefile b/Makefile
index 66cf39b..bf2a5dc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
CC=gcc
# Enable debugging
-CFLAGS=-ggdb -O3
+CFLAGS=-ggdb -O3 -Wall
# We need math
LDFLAGS=-lm -lpthread
diff --git a/ctranslate.c b/ctranslate.c
index f7dfe64..8d03d39 100644
--- a/ctranslate.c
+++ b/ctranslate.c
@@ -1,9 +1,11 @@
#include "ctranslate.h"
+#include "vector.h"
#include <math.h>
// TODO remove dublicate pi definitions
#define PI 3.14159265359
+#define DEBUG 0
void csystem_init(csystem_t *cs, vector_t *up)
{
@@ -11,23 +13,35 @@ void csystem_init(csystem_t *cs, vector_t *up)
// Create new coordinate system where N is up. To do this we need two more vectors for the other axises.
// Create the 2. by setting x or y to 0
- if (up->x > up->y) {
+ if (fabs(up->x) > fabs(up->y)) {
vector_set(&cs->ax, up->z, 0, -up->x);
} else {
vector_set(&cs->ax, 0, -up->z, up->y);
}
// Normalice
- vector_scale_inv(&cs->ax, &cs->ax, vector_len(&cs->ax));
+ vector_norm(&cs->ax);
+
// Create the 3. axis by taking the cross of the other
vector_cross(&cs->az, up, &cs->ax);
+#if DEBUG == 1
+ printf("up "); vector_print(up);
+ printf("ax "); vector_print(&cs->ax);
+ printf("az "); vector_print(&cs->az);
+#endif
}
void csystem_calc_real(csystem_t *cs, vector_t *inside, vector_t *real)
{
- vector_set(real, inside->x * cs->ax.x + inside->y * cs->up->x + inside->z * cs->az.x,
+ vector_t tmp;
+ vector_set(&tmp, inside->x * cs->ax.x + inside->y * cs->up->x + inside->z * cs->az.x,
inside->x * cs->ax.y + inside->y * cs->up->y + inside->z * cs->az.y,
inside->x * cs->ax.z + inside->y * cs->up->z + inside->z * cs->az.z);
+
+ vector_copy(real, &tmp);
+#if DEBUG == 1
+ printf("Haha "); vector_print(real);
+#endif
}
void csystem_hemisphere_random(csystem_t *cs, COORD_T r1, COORD_T r2, vector_t *out)
diff --git a/main.c b/main.c
index e4c8c1a..356976a 100644
--- a/main.c
+++ b/main.c
@@ -37,15 +37,27 @@ container_t *cont = (container_t *) container;
settings_t gfx_high = {
.arealight_samples = 64,
.envlight_samples = 64,
- .antialias_samples = 8,
- .depth = 16,
+ .antialias_samples = 2,
+ .globallight_samples = 32,
+ .gl_opt_depth = 1,
+ .depth = 2,
};
settings_t gfx_low = {
.arealight_samples = 16,
.envlight_samples = 16,
.antialias_samples = 2,
- .globallight_samples = 5,
+ .globallight_samples = 16,
+ .gl_opt_depth = 1,
+ .depth = 1,
+};
+
+settings_t gfx_very = {
+ .arealight_samples = 8,
+ .envlight_samples = 8,
+ .antialias_samples = 2,
+ .globallight_samples = 2,
+ .gl_opt_depth = 0,
.depth = 1,
};
@@ -64,7 +76,8 @@ int main()
// Set space options
color_set(&s->ambient, 0.09, 0.09, 0.09);
- color_set(&s->back, 0.8, 0.8, 0.8);
+ //color_set(&s->back, 0.8, 0.8, 0.8);
+ color_set(&s->back, 0.0, 0.0, 0.0);
color_set(&s->env_color, 0.13, 0.13, 0.13);
s->env_enabled = false;
s->gfx = &gfx_low;
@@ -166,7 +179,7 @@ int main()
o->m = ml;
light_t *l = add_light(cont, TYPE_L_AREA);
- //vector_set(&l->point.pos, 2, 8, -1);
+ //vector_set(&l->point.pos, 0, 5, 0);
l->area = o;
color_set(&l->color, 1, 1, 1);
l->radiance = 0.1;
diff --git a/ray.c b/ray.c
index e2789ca..83708f6 100644
--- a/ray.c
+++ b/ray.c
@@ -135,30 +135,28 @@ object_t *ray_cast(space_t *s, ray_t *r, COORD_T *dist_ret, bool chk, COORD_T ch
return smallest;
}
-// Light (l) the object o reflects. Given is the point of intersect, vector to the light l, vector to viewer V, and normal at point N.
-static void reflected_at(object_t *o, color_t *dest, light_t *light, COORD_T dist, vector_t *point, vector_t *l, vector_t *V, vector_t *N) {
- // Calculate light intensity
- COORD_T i = light->radiance / ( dist * dist);
+// Color the object o reflects. Given is the point of intersect, vector to the light dir, vector to viewer V, and normal at point N.
+static void reflected_at(object_t *o, color_t *dest, color_t *incolor, COORD_T intensity, vector_t *point, vector_t *dir, vector_t *V, vector_t *N) {
// Calculate Deffuse part
color_t tmp;
- COORD_T cl = vector_dot(l, N) * i;
+ COORD_T cl = vector_dot(dir, N) * intensity;
if (cl > 0) {
- color_scale(&tmp, &light->color, cl * o->m->defuse);
+ color_scale(&tmp, incolor, cl * o->m->defuse);
color_add(dest, &tmp, dest);
}
// 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);
+ vector_scale(&R, N, 2 * vector_dot(dir, N));
+ vector_sub(&R, &R, dir);
// Add it to the light
- cl = vector_dot(&R, V) * i;
+ cl = vector_dot(&R, V) * intensity;
if (cl > 0) {
cl = pow(cl, o->m->shine);
- color_scale(&tmp, &light->color, cl * o->m->specular);
+ color_scale(&tmp, incolor, cl * o->m->specular);
color_add(dest, &tmp, dest);
}
}
@@ -177,7 +175,7 @@ static void contribution_from_pointlight(space_t *s, color_t *dest, object_t *o,
COORD_T d = vector_len(&l);
// Normalice
- vector_scale_inv(&l, &l, vector_len(&l));
+ vector_norm(&l);
// Find obstacles
r.direction = &l;
@@ -187,7 +185,8 @@ static void contribution_from_pointlight(space_t *s, color_t *dest, object_t *o,
}
// Calculate the reflected light
- reflected_at(o, dest, light, d, point, &l, V, N);
+ COORD_T i = light->radiance / ( d * d);
+ reflected_at(o, dest, &light->color, i, point, &l, V, N);
}
// Many of these can maybe be put in a context struct
@@ -206,7 +205,7 @@ static void contribution_from_arealight(space_t *s, color_t *dest, object_t *o,
// Calculate vector from light to point
vector_t l;
vector_sub(&l, point, &light->area->sph.center);
- vector_scale_inv(&l, &l, vector_len(&l));
+ vector_norm(&l);
// Initialize the transformation stuff
csystem_t cs;
@@ -241,8 +240,9 @@ static void contribution_from_arealight(space_t *s, color_t *dest, object_t *o,
continue;
}
- // Add the light contribution, Not sure why it is scaled
- reflected_at(o, &c, light, dist, point, &randpoint, V, N);
+ // Add the light contribution
+ COORD_T i = light->radiance / ( dist * dist);
+ reflected_at(o, &c, &light->color, i, point, &randpoint, V, N);
}
@@ -260,7 +260,7 @@ static void direct_light(space_t *s, color_t *dest, object_t *o, vector_t *N, ve
vector_sub(&V, eye, point);
// Normalice it
- vector_scale_inv(&V, &V, vector_len(&V));
+ vector_norm(&V);
// Loop lights
light_t *light = s->lights;
@@ -348,8 +348,16 @@ static void global_light(space_t *s, color_t *dest, object_t *o, vector_t *N, ve
// Value for accumilating colors
color_t acc;
color_set(&acc, 0, 0, 0);
-
- for (unsigned i = 0; i < s->gfx->globallight_samples; i++) {
+
+ // Samples is lowered for every hop
+ unsigned samples;
+ if (hop < s->gfx->gl_opt_depth) {
+ samples = s->gfx->globallight_samples / (hop + 1);
+ } else {
+ samples = s->gfx->globallight_samples / (s->gfx->gl_opt_depth + 1);
+ }
+
+ for (unsigned i = 0; i < samples; i++) {
COORD_T r1 = ray_rand(seed);
// Calculate the random direction vector
@@ -361,15 +369,25 @@ static void global_light(space_t *s, color_t *dest, object_t *o, vector_t *N, ve
// Check the direction for obstacles
r.direction = &randdir;
-
- // Cast ray in direction if we have more hops
- if (hop < s->gfx->depth) {
- ray_trace_recur(s, &acc, &r, hop+1, r1, seed);
+ COORD_T cl = vector_dot(&randdir, N);
+
+ // Only recurse if neccesary
+ if (cl > 0.01) {
+ // Cast ray in direction if we have more hops
+ color_t tmp;
+ color_set(&tmp, 0, 0, 0);
+ if (hop < s->gfx->depth) {
+ ray_trace_recur(s, &tmp, &r, hop+1, r1, seed);
+ }
+
+ // Calculate Deffuse light
+ color_scale(&tmp, &tmp, cl * o->m->defuse);
+ color_add(&acc, &tmp, &acc);
}
}
// Devide by number of samples and pdf
- color_scale(&acc, &acc, ((COORD_T) 1/ s->gfx->globallight_samples) * (2 * PI));
+ color_scale(&acc, &acc, ((COORD_T) 1/ samples) * (2 * PI));
// Add to dest
color_add(dest, dest, &acc);
@@ -378,15 +396,15 @@ static void global_light(space_t *s, color_t *dest, object_t *o, vector_t *N, ve
int ray_trace_recur(space_t *s, color_t *dest, ray_t *ray, unsigned hop, COORD_T scale, void *seed)
{
COORD_T dist;
- color_t c;
- color_set(&c, 0, 0, 0);
object_t *o = ray_cast(s, ray, &dist, false, 0);
if (!o) {
- color_add(&c, &c, &s->back);
- goto exit;
+ return 1;
}
+ color_t c;
+ color_set(&c, 0, 0, 0);
+
vector_t rdir, rstart;
ray_t r = {.start = &rstart, .direction = &rdir};
@@ -406,6 +424,7 @@ int ray_trace_recur(space_t *s, color_t *dest, ray_t *ray, unsigned hop, COORD_T
if (o->m->defuse + o->m->specular > ZERO_APROX) {
// Add all light hitting o at r.start to c
direct_light(s, &c, o, &N, ray->start, r.start, seed);
+ global_light(s, &c, o, &N, r.start, hop, seed);
}
// Calculate environmental light
@@ -413,7 +432,6 @@ int ray_trace_recur(space_t *s, color_t *dest, ray_t *ray, unsigned hop, COORD_T
env_light(s, &c, o, &N, r.start, seed);
}
- global_light(s, &c, o, &N, r.start, hop, seed);
// Calculate reflection vector
if (hop < 10 && o->m->reflective > ZERO_APROX) {
@@ -459,7 +477,10 @@ void ray_trace(space_t *s, unsigned int x, unsigned int y, color_t *c, void *see
viewpoint_ray(&s->view, r.direction, x + tmp, y + tmp);
// Run the recursive ray trace
- ray_trace_recur(s, &ctmp, &r, 0, 1, seed);
+ if (ray_trace_recur(s, &ctmp, &r, 0, 1, seed)) {
+ // Hit nothing add back
+ color_add(&ctmp, &ctmp, &s->back);
+ }
// Color_add will not go above 1. In this case we don't want that.
c->r += ctmp.r; c->g += ctmp.g; c->b += ctmp.b;
diff --git a/scene.h b/scene.h
index 738f143..e7ee95f 100644
--- a/scene.h
+++ b/scene.h
@@ -80,6 +80,7 @@ typedef struct {
unsigned globallight_samples;
unsigned depth;
+ unsigned gl_opt_depth;
} settings_t;
typedef struct {
diff --git a/vector.c b/vector.c
index 0bcd1dc..661516e 100644
--- a/vector.c
+++ b/vector.c
@@ -43,6 +43,17 @@ COORD_T vector_len(vector_t *v)
return sqrt( v->x * v->x + v->y * v->y + v->z * v->z );
}
+void vector_norm(vector_t *v)
+{
+ COORD_T len = vector_len(v);
+ if (len == 0) {
+ vector_set(v, 0, 0, 0);
+ return;
+ }
+
+ vector_scale_inv(v, v, len);
+}
+
vector_t *vector_add(vector_t *dest, vector_t *a, vector_t *b)
{
dest = vector_exists(dest);
diff --git a/vector.h b/vector.h
index 81b5df1..7e4dccb 100644
--- a/vector.h
+++ b/vector.h
@@ -18,6 +18,7 @@ vector_t *vector_copy(vector_t *dest, vector_t *src);
// Calculate the length of v
COORD_T vector_len(vector_t *v);
+void vector_norm(vector_t *v);
COORD_T vector_dot(vector_t *a, vector_t *b);