From 6ae610fd7f28ba5ba7a8e0233cd6fb0ac5df4a8b Mon Sep 17 00:00:00 2001 From: Julian T Date: Mon, 23 Mar 2020 15:56:54 +0100 Subject: Random is generated by user defined function --- main.c | 11 ++++++++++- ray.c | 16 ++++++++-------- ray.h | 6 +++++- test.png | Bin 696052 -> 693556 bytes 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 1ea89fa..36a9372 100644 --- a/main.c +++ b/main.c @@ -12,6 +12,12 @@ char container[ CONTAINER_SIZE(5, 4, 1) ]; +// Implement random +COORD_T ray_rand(void *seed) +{ + return (COORD_T) rand_r( (int *)seed ) / RAND_MAX; +} + int main() { @@ -81,10 +87,13 @@ int main() // Height percentage unsigned percentstep = TESTH / 100; unsigned percent = 0; + int seed; for (int y = TESTH; y; y--) { for (int x = TESTW; x; x--) { - color_t *c = ray_trace(&cont->space, x, y, 2); + // Random seed + seed = x * y; + color_t *c = ray_trace(&cont->space, x, y, 2, &seed); if (c) { pgm_write_pixel(stdout, c); diff --git a/ray.c b/ray.c index 07807c0..b2df086 100644 --- a/ray.c +++ b/ray.c @@ -191,7 +191,7 @@ static void direct_light(space_t *s, color_t *dest, object_t *o, vector_t *N, ve // Calculates the global illumination. Pretty slow // https://www.scratchapixel.com/lessons/3d-basic-rendering/global-illumination-path-tracing/global-illumination-path-tracing-practical-implementation -static void env_light(space_t *s, color_t *dest, object_t *o, vector_t *N, vector_t *eye, vector_t *point) +static void env_light(space_t *s, color_t *dest, object_t *o, vector_t *N, vector_t *point, void *seed) { // 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 @@ -218,8 +218,8 @@ static void env_light(space_t *s, color_t *dest, object_t *o, vector_t *N, vecto for (unsigned i = 0; i < s->env_samples; i++) { // Do the monte carlo random distribution thing from the article - COORD_T r1 = (COORD_T) rand() / RAND_MAX; - COORD_T r2 = (COORD_T) rand() / RAND_MAX; + COORD_T r1 = ray_rand(seed); + COORD_T r2 = ray_rand(seed); COORD_T sinTheta = sqrt(1 - r1 * r1); COORD_T phi = 2 * PI * r2; @@ -256,7 +256,7 @@ static void env_light(space_t *s, color_t *dest, object_t *o, vector_t *N, vecto } -int ray_trace_recur(space_t *s, color_t *dest, ray_t *ray, unsigned hop, COORD_T scale) +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; @@ -286,7 +286,7 @@ int ray_trace_recur(space_t *s, color_t *dest, ray_t *ray, unsigned hop, COORD_T // Calculate environmental light if (s->env_samples) { - env_light(s, &c, o, &N, ray->start, r.start); + env_light(s, &c, o, &N, r.start, seed); } // Calculate reflection vector @@ -294,7 +294,7 @@ int ray_trace_recur(space_t *s, color_t *dest, ray_t *ray, unsigned hop, COORD_T 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); + ray_trace_recur(s, &c, &r, hop+1, o->m->reflective, seed); } @@ -309,7 +309,7 @@ exit: return 0; } -color_t *ray_trace(space_t *s, unsigned int x, unsigned int y, unsigned samples) +color_t *ray_trace(space_t *s, unsigned int x, unsigned int y, unsigned samples, void *seed) { // Init return color. Will be accumilated with all the detected light. color_t *c = color_set(NULL, 0, 0, 0); @@ -331,7 +331,7 @@ color_t *ray_trace(space_t *s, unsigned int x, unsigned int y, unsigned samples) viewpoint_ray(&s->view, r.direction, x + tmp, y + tmp); // Run the recursive ray trace - ray_trace_recur(s, &ctmp, &r, 0, 1); + ray_trace_recur(s, &ctmp, &r, 0, 1, seed); // 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/ray.h b/ray.h index 74749ff..4f7fe0c 100644 --- a/ray.h +++ b/ray.h @@ -6,6 +6,9 @@ #include "vector.h" #include "scene.h" +// Random COORD_T between 0 and 1 +extern COORD_T ray_rand(void *seed); + typedef struct { // Start is not unique so it's a pointer to save copying time vector_t *start; @@ -17,6 +20,7 @@ COORD_T ray_intersect_sphere(sphere_t *s, ray_t *ray, bool skip_dist); COORD_T ray_intersect_plane(plane_t *p, ray_t *ray, bool skip_dist); object_t *ray_cast(space_t *s, ray_t *r, COORD_T *dist_ret, bool chk, COORD_T chk_dist); -color_t *ray_trace(space_t *s, unsigned int x, unsigned int y, unsigned samples); +color_t *ray_trace(space_t *s, unsigned int x, unsigned int y, unsigned samples, void *seed); + #endif diff --git a/test.png b/test.png index 70122a6..10bb6ce 100644 Binary files a/test.png and b/test.png differ -- cgit v1.2.3