star-mc

Parallel estimation of Monte Carlo integrators
git clone git://git.meso-star.fr/star-mc.git
Log | Files | Refs | README | LICENSE

commit ac7c9edf63de832c06b6059845f18a2561d98bc4
parent ac0e6a010b1acb8685d0a7b7fd56f2b25311d7d8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  8 Apr 2015 09:13:18 +0200

Finalize the light path test

Diffstat:
Msrc/smc_integrator.c | 2+-
Msrc/test_smc_light_path.c | 61++++++++++++++++++++++++++++++++++++++++++++++---------------
2 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/src/smc_integrator.c b/src/smc_integrator.c @@ -124,7 +124,7 @@ smc_solve estimator->status.N = 0; estimator->type = *type; - FOR_EACH(i, 0, 4096) { + FOR_EACH(i, 0, 16) { if(estimator->nsamples == ULONG_MAX) break; integrand(val, dev->rng, ctx); type->add(estimator->value, estimator->value, val); diff --git a/src/test_smc_light_path.c b/src/test_smc_light_path.c @@ -44,8 +44,9 @@ #define IMG_WIDTH 640 #define IMG_HEIGHT 480 #define LIGHT_PATH_DEPTH 4 -#define SKY_RADIANCE 1.f +#define SKY_RADIANCE 0.1f #define ALBEDO 1.f +#define EPSILON 1.e-3f struct cbox_desc{ const float* vertices; @@ -201,6 +202,30 @@ struct integrator_context { size_t ipixel[2]; /* Image space pixel coordinates */ }; +static float +direct_lighting(struct s3d_scene* scn, const float pos[3], const float N[3]) +{ + const float light_pos[3] = { 200.f, 0.f, 400.f }; + const float radiance = 20000.f; + struct s3d_hit hit; + float len; + float wi[3]; + float range[2]; + + f3_sub(wi, light_pos, pos); + len = f3_normalize(wi, wi); + + /* Trace shadow ray */ + range[0] = EPSILON; + range[1] = len; + CHECK(s3d_scene_trace_ray(scn, pos, wi, range, &hit), RES_OK); + + if(!S3D_HIT_NONE(&hit)) + return 0.f; + + return (radiance * (float)(ALBEDO / PI)) / (len*len) * f3_dot(wi, N); +} + static void light_path_integrator(void* value, struct ssp_rng* rng, void* data) { @@ -233,29 +258,35 @@ light_path_integrator(void* value, struct ssp_rng* rng, void* data) FOR_EACH(idepth, 0, LIGHT_PATH_DEPTH) { struct s3d_hit hit = S3D_HIT_NULL; float cos_theta; - float offset = 1.e-6f; + float sample[4]; float pdf; - float wi[3]; + float pos[3]; float N[3]; CHECK(s3d_scene_trace_ray (ctx->scn, ray_org, ray_dir, ray_range, &hit), RES_OK); - if(!S3D_HIT_NONE(&hit)) { /* Skydome lighting */ + if(S3D_HIT_NONE(&hit)) { /* Skydome lighting */ L += throughput * SKY_RADIANCE; break; } - /* TODO sample the surface hemisphere at the hit position */ + f3_normalize(N, hit.normal); + cos_theta = f3_dot(N, ray_dir); + if(cos_theta >= 0.f) f3_minus(N, N); + f3_add(pos, f3_mulf(pos, ray_dir, hit.distance), ray_org); + + /* Direct lighting */ + L += throughput * direct_lighting(ctx->scn, pos, N); /* New ray */ - f3_normalize(N, hit.normal); - cos_theta = f3_dot(N, wi); - if(cos_theta < 0.f) f3_dot(f3_minus(N, N), wi); - f3_mulf(ray_org, ray_dir, hit.distance); - f3_set(ray_dir, wi); - ray_range[0] = offset; - throughput *= ALBEDO / pdf * cos_theta; + ssp_ran_hemisphere_cos(rng, N, sample); + pdf = sample[3]; + cos_theta = f3_dot(N, sample); + f3_set(ray_org, pos); + f3_set(ray_dir, sample); + ray_range[0] = EPSILON; + throughput *= (float)(ALBEDO / PI) / pdf * cos_theta; } *(float*)value = L; } @@ -273,7 +304,7 @@ main(int argc, char** argv) struct s3d_shape* shape; struct s3d_vertex_data attribs[2]; struct smc_device* smc; - unsigned char* img; + unsigned char* img = NULL; size_t ix, iy; float pos[3]; (void)argc, (void)argv; @@ -343,8 +374,8 @@ main(int argc, char** argv) unsigned char colu; CHECK(smc_estimator_get_status(estimator, &status), RES_OK); - col = CLAMP(SMC_FLOAT(status.E), 0.f, 1.f); - colu = (unsigned char)(col * 255.f); + col = (float)pow(SMC_FLOAT(status.E), 1.0/2.2); /* Gamma correction */ + colu = (unsigned char)(CLAMP(col, 0.f, 1.f) * 255.f); /* Float to U8 */ img[ipix + 0] = colu; img[ipix + 1] = colu; img[ipix + 2] = colu;