solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit b3e48bafd23ff9eef9e329e4eb87a51b54358031
parent c628c73deac8ebecdb3f3a3322d903c08113af1c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  8 Mar 2017 15:56:58 +0100

Update the API of the ssol_draw_<draft|pt> functions

Add the number of samples per pixel to the function arguments.

Diffstat:
Mcmake/CMakeLists.txt | 1+
Msrc/ssol.h | 2++
Msrc/ssol_draw_draft.c | 65++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/ssol_draw_pt.c | 15++++++++-------
Msrc/test_ssol_draw.c | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
5 files changed, 139 insertions(+), 48 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -172,6 +172,7 @@ if(NOT NO_TEST) build_test(test_ssol_draw) register_test(test_ssol_draw_draft test_ssol_draw draft) + register_test(test_ssol_draw_pt test_ssol_draw pt) endif() diff --git a/src/ssol.h b/src/ssol.h @@ -956,6 +956,7 @@ ssol_draw_draft struct ssol_camera* cam, const size_t width, /* #pixels in X */ const size_t height, /* #pixels in Y */ + const size_t spp, /* #samples per pixel */ ssol_write_pixels_T writer, void* writer_data); @@ -965,6 +966,7 @@ ssol_draw_pt struct ssol_camera* cam, const size_t width, /* #pixels in X */ const size_t height, /* #pixels in Y */ + const size_t spp, ssol_write_pixels_T writer, void* writer_data); diff --git a/src/ssol_draw_draft.c b/src/ssol_draw_draft.c @@ -15,14 +15,18 @@ #include "ssol_c.h" #include "ssol_camera.h" +#include "ssol_device_c.h" #include "ssol_draw.h" #include "ssol_object_c.h" #include "ssol_scene_c.h" #include "ssol_shape_c.h" #include <rsys/double3.h> +#include <rsys/dynamic_array_float.h> #include <rsys/float3.h> +#include <star/ssp.h> + #include <float.h> /******************************************************************************* @@ -82,15 +86,31 @@ draw_pixel double pixel[3], void* ctx) { + struct darray_float* samples = ctx; float samp[2]; float ray_org[3], ray_dir[3]; - ASSERT(scn && cam && view && pix_coords && pix_sz && nsamples && pixel); - (void)ithread, (void)ctx, (void)nsamples; + double sum[3] = {0, 0, 0}; + size_t i; + ASSERT(scn && cam && view && pix_coords && pix_sz && nsamples && pixel && ctx); + (void)ithread; + + FOR_EACH(i, 0, nsamples) { + double weight[3]; + const float* r = darray_float_cdata_get(samples) + i*2; + + /* Generate a sample into the pixel */ + samp[0] = ((float)pix_coords[0] + r[0]) * pix_sz[0]; + samp[1] = ((float)pix_coords[1] + r[1]) * pix_sz[1]; - samp[0] = ((float)pix_coords[0] + 0.5f) * pix_sz[0]; - samp[1] = ((float)pix_coords[1] + 0.5f) * pix_sz[1]; - camera_ray(cam, samp, ray_org, ray_dir); - Li(scn, view, ray_org, ray_dir, pixel); + /* Generate a ray starting from the pinhole camera and passing through the + * pixel sample */ + camera_ray(cam, samp, ray_org, ray_dir); + + /* Compute the radiance arriving through the sampled camera ray */ + Li(scn, view, ray_org, ray_dir, weight); + d3_add(sum, sum, weight); + } + d3_divd(pixel, sum, (double)nsamples); } @@ -103,9 +123,40 @@ ssol_draw_draft struct ssol_camera* cam, const size_t width, const size_t height, + const size_t spp, ssol_write_pixels_T writer, void* data) { - return draw(scn, cam, width, height, 1, writer, data, draw_pixel, NULL); + struct darray_float samples; + struct ssp_rng* rng = NULL; + size_t i; + res_T res = RES_OK; + + if(!scn || !spp) return RES_BAD_ARG; + + darray_float_init(scn->dev->allocator, &samples); + res = darray_float_reserve(&samples, spp * 2/*#dimensions*/); + if(res != RES_OK) goto error; + + res = ssp_rng_create(scn->dev->allocator, &ssp_rng_threefry, &rng); + if(res != RES_OK) goto error; + + /* Generate the pixel samples */ + FOR_EACH(i, 0, spp) { + const float x = ssp_rng_canonical_float(rng); + const float y = ssp_rng_canonical_float(rng); + darray_float_push_back(&samples, &x); + darray_float_push_back(&samples, &y); + } + + res = draw(scn, cam, width, height, spp, writer, data, draw_pixel, &samples); + if(res != RES_OK) goto error; + +exit: + darray_float_release(&samples); + if(rng) SSP(rng_ref_put(rng)); + return res; +error: + goto exit; } diff --git a/src/ssol_draw_pt.c b/src/ssol_draw_pt.c @@ -238,15 +238,15 @@ draw_pixel { struct darray_thread_context* thread_ctxs = data; struct thread_context* ctx; - double L[3]; + double sum[3] = {0, 0, 0}; size_t isample; - ASSERT(scn && cam && pix_coords && pix_sz && nsamples && pixel && ctx); + ASSERT(scn && cam && pix_coords && pix_sz && nsamples && pixel && data); ASSERT((size_t)ithread < darray_thread_context_size_get(thread_ctxs)); ctx = darray_thread_context_data_get(thread_ctxs) + ithread; - d3_splat(pixel, 0); FOR_EACH(isample, 0, nsamples) { + double weight[3]; float samp[2]; /* Pixel sample */ float ray_org[3], ray_dir[3]; @@ -259,11 +259,11 @@ draw_pixel camera_ray(cam, samp, ray_org, ray_dir); /* Compute the radiance arriving through the sampled camera ray */ - Li(scn, ctx, view, ray_org, ray_dir, L); - d3_add(pixel, pixel, L); + Li(scn, ctx, view, ray_org, ray_dir, weight); + d3_add(sum, sum, weight); } - d3_divd(pixel, pixel, (double)nsamples); /* Expected value */ + d3_divd(pixel, sum, (double)nsamples); } /******************************************************************************* @@ -275,6 +275,7 @@ ssol_draw_pt struct ssol_camera* cam, const size_t width, const size_t height, + const size_t spp, ssol_write_pixels_T writer, void* data) { @@ -310,7 +311,7 @@ ssol_draw_pt } /* Invoke the draw process */ - res = draw(scn, cam, width, height, 4, writer, data, draw_pixel, &thread_ctxs); + res = draw(scn, cam, width, height, spp, writer, data, draw_pixel, &thread_ctxs); if(res != RES_OK) goto error; exit: diff --git a/src/test_ssol_draw.c b/src/test_ssol_draw.c @@ -25,8 +25,8 @@ #include <string.h> -#define WIDTH 800 -#define HEIGHT 600 +#define WIDTH 256 +#define HEIGHT 256 #define PITCH (WIDTH*sizeof(unsigned char[3])) #define PROJ_RATIO ((double)WIDTH/(double)HEIGHT) @@ -193,6 +193,7 @@ main(int argc, char** argv) struct ssol_camera* cam, const size_t width, const size_t height, + const size_t spp, ssol_write_pixels_T writer, void* data); (void)argc, (void)argv; @@ -206,6 +207,9 @@ main(int argc, char** argv) draw_func = ssol_draw_draft; } else if(!strcmp(argv[1], "pt")) { draw_func = ssol_draw_pt; + } else { + fprintf(stderr, "Usage: %s <draft|pt>\n", argv[0]); + return -1; } CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK); @@ -232,38 +236,70 @@ main(int argc, char** argv) pixels = MEM_CALLOC(&allocator, HEIGHT, PITCH); NCHECK(pixels, NULL); - CHECK(draw_func(NULL, NULL, 0, 0, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, NULL, 0, 0, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, cam, 0, 0, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, cam, 0, 0, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, cam, WIDTH, WIDTH, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, cam, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(NULL, cam, WIDTH, WIDTH, write_RGB8, pixels), RES_BAD_ARG); - CHECK(draw_func(scn, cam, WIDTH, HEIGHT, write_RGB8, pixels), RES_OK); + CHECK(draw_func(NULL, NULL, 0, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, HEIGHT, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, HEIGHT, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, HEIGHT, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, HEIGHT, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, WIDTH, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, HEIGHT, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, HEIGHT, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, HEIGHT, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, HEIGHT, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, HEIGHT, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, HEIGHT, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, 0, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, 0, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, 0, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, 0, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, 0, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, 0, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, 0, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, 0, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, HEIGHT, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, HEIGHT, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, HEIGHT, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, HEIGHT, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, WIDTH, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, HEIGHT, 4, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, 0, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, 0, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, 0, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, 0, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, 0, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, 0, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, 0, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, 0, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, HEIGHT, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, HEIGHT, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, HEIGHT, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, HEIGHT, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, WIDTH, 4, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, HEIGHT, 4, write_RGB8, pixels), RES_OK); CHECK(image_ppm_write_stream(stdout, WIDTH, HEIGHT, 3, pixels), RES_OK);