solstice-solver

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

commit 7f305ca7677795f827f5a7ee59f7ca9b97d4ed4c
parent e533c1aa7cbfe3e83462f023bc04569de7b00605
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  6 Sep 2016 12:14:21 +0200

Merge remote-tracking branch 'origin/master'

Diffstat:
Msrc/ssol_brdf.h | 6+++---
Msrc/ssol_brdf_composite.c | 14+++++++-------
Msrc/ssol_brdf_composite.h | 6+++---
Msrc/ssol_brdf_reflection.c | 20++++++++++----------
Msrc/ssol_material.c | 8++++----
Msrc/ssol_material_c.h | 4++--
Msrc/ssol_object_instance.c | 3+++
Msrc/ssol_object_instance_c.h | 1+
Msrc/ssol_solver.c | 50++++++++++++++++++++++++++++----------------------
Msrc/ssol_solver_c.h | 5++---
10 files changed, 63 insertions(+), 54 deletions(-)

diff --git a/src/ssol_brdf.h b/src/ssol_brdf.h @@ -24,9 +24,9 @@ typedef double /* Sampled radiance */ (*brdf_sample_func_T) (void* data, /* BRDF internal data */ struct ssp_rng* rng, /* Random Number Generator */ - const float w[3], /* Incoming direction. Point toward the surface */ - const float N[3], /* Normalized normal */ - float dir[4]); /* Sampled direction. The PDF is stored in dir[3] */ + const double w[3], /* Incoming direction. Point toward the surface */ + const double N[3], /* Normalized normal */ + double dir[4]); /* Sampled direction. The PDF is stored in dir[3] */ /* Generic Bidirectional Reflectance Distribution Function */ struct brdf { diff --git a/src/ssol_brdf_composite.c b/src/ssol_brdf_composite.c @@ -19,7 +19,7 @@ #include "ssol_device_c.h" #include <rsys/dynamic_array.h> -#include <rsys/float4.h> +#include <rsys/double4.h> #include <rsys/ref_count.h> #include <star/ssp.h> @@ -122,13 +122,13 @@ double brdf_composite_sample (struct brdf_composite* brdfs, struct ssp_rng* rng, - const float w[3], - const float N[3], - float dir[4]) + const double w[3], + const double N[3], + double dir[4]) { const size_t PDF = 3; double radiances[MAX_COMPONENTS]; - float dirs[MAX_COMPONENTS][4]; + double dirs[MAX_COMPONENTS][4]; double probas[MAX_COMPONENTS]; double cumul[MAX_COMPONENTS]; double probas_sum; @@ -152,7 +152,7 @@ brdf_composite_sample } if(!n) { /* No valid component to sample */ - f4_splat(dir, 0.f); + d4_splat(dir, 0); return 0; } @@ -167,7 +167,7 @@ brdf_composite_sample /* Finally sample the distribution */ r = ssp_rng_canonical(rng); FOR_EACH(i, 0, n-1) if(r <= cumul[i]) break; - f4_set(dir, dirs[i]); + d4_set(dir, dirs[i]); return radiances[i]; } diff --git a/src/ssol_brdf_composite.h b/src/ssol_brdf_composite.h @@ -51,9 +51,9 @@ extern LOCAL_SYM double brdf_composite_sample (struct brdf_composite* brdfs, struct ssp_rng* rng, - const float w[3], /* Incoming direction */ - const float N[3], /* Normalized normal */ - float dir[4]); /* Sampled direction. The PDF is stored in dir[3] */ + const double w[3], /* Incoming direction */ + const double N[3], /* Normalized normal */ + double dir[4]); /* Sampled direction. The PDF is stored in dir[3] */ #endif /* SSOL_BRDF_COMPOSITE_H */ diff --git a/src/ssol_brdf_reflection.c b/src/ssol_brdf_reflection.c @@ -16,7 +16,7 @@ #include "ssol_device_c.h" #include "ssol_brdf_reflection.h" -#include <rsys/float3.h> +#include <rsys/double3.h> struct brdf_reflection { double reflectivity; @@ -29,20 +29,20 @@ static double reflection_sample (void* data, struct ssp_rng* rng, - const float w[3], - const float N[3], - float dir[4]) + const double w[3], + const double N[3], + double dir[4]) { struct brdf_reflection* reflection = data; - float cosi; + double cosi; (void)rng; - ASSERT(w && N && dir && f3_is_normalized(N) && f3_is_normalized(w) && data); + ASSERT(w && N && dir && d3_is_normalized(N) && d3_is_normalized(w) && data); /* Simply reflect the incoming direction w[3] with respect to the normal */ - cosi = -f3_dot(w, N); - f3_mulf(dir, N, 2.f*cosi); - f3_add(dir, dir, w); - dir[3] = 1.f; /* pdf */ + cosi = -d3_dot(w, N); + d3_muld(dir, N, 2*cosi); + d3_add(dir, dir, w); + dir[3] = 1; /* pdf */ return reflection->reflectivity; } diff --git a/src/ssol_material.c b/src/ssol_material.c @@ -191,8 +191,8 @@ ssol_material_create_virtual void surface_fragment_setup (struct surface_fragment* fragment, - const float pos[3], - const float dir[3], + const double pos[3], + const double dir[3], const float normal[3], const struct s3d_primitive* primitive, const float uv[2]) @@ -202,10 +202,10 @@ surface_fragment_setup ASSERT(fragment && pos && dir && primitive && uv); /* Setup the incoming direction */ - d3_set_f3(fragment->dir, dir); + d3_set(fragment->dir, dir); /* Setup the surface position */ - d3_set_f3(fragment->pos, pos); + d3_set(fragment->pos, pos); /* Normalize the geometry normal */ d3_set_f3(fragment->Ng, normal); diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h @@ -56,8 +56,8 @@ struct ssol_material { extern LOCAL_SYM void surface_fragment_setup (struct surface_fragment* fragment, - const float pos[3], - const float dir[3], + const double pos[3], + const double dir[3], const float normal[3], const struct s3d_primitive* primitive, const float uv[2]); diff --git a/src/ssol_object_instance.c b/src/ssol_object_instance.c @@ -22,6 +22,7 @@ #include <rsys/rsys.h> #include <rsys/mem_allocator.h> #include <rsys/ref_count.h> +#include <rsys/double33.h> #include <string.h> @@ -75,6 +76,8 @@ ssol_object_instantiate instance->dev = dev; instance->object = object; + d33_set_identity(instance->transform); + d3_splat(instance->transform + 9, 0); instance->target_mask = 0; str_init(dev->allocator, &instance->receiver_name); SSOL(object_ref_get(object)); diff --git a/src/ssol_object_instance_c.h b/src/ssol_object_instance_c.h @@ -26,6 +26,7 @@ struct ssol_object_instance struct s3d_shape* shape_rt; /* Instantiated Star-3D shape to ray-trace */ struct s3d_shape* shape_samp; /* Instantiated Star-3D shape to sample */ struct str receiver_name; /* Empty if not a receiver */ + double transform[12]; uint32_t target_mask; struct ssol_device* dev; diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -54,6 +54,17 @@ get_quadric(const struct ssol_object_instance* instance) return &instance->object->shape->quadric; } +static FINLINE void +solstice_trace_ray(struct realisation* rs) +{ + float org[3], dir[3]; + struct segment* seg = current_segment(rs); + f3_set_d3(org, seg->org); + f3_set_d3(dir, seg->dir); + S3D(scene_view_trace_ray + (rs->data.view_rt, org, dir, seg->range, rs, &seg->hit)); +} + /******************************************************************************* * Local functions ******************************************************************************/ @@ -327,7 +338,7 @@ sample_point_on_primary_mirror(struct realisation* rs) switch (object->shape->type) { case SHAPE_MESH: /* no projection needed */ - f3_set(seg->org, attrib.value); + d3_set_f3(seg->org, attrib.value); /* to avoid self intersect */ rs->start.primitive = tmp_prim; break; @@ -359,21 +370,19 @@ sample_wavelength(struct realisation* rs) static int receive_sunlight(struct realisation* rs) { - float sundir_f[3]; struct s3d_attrib attrib; struct segment* seg = sun_segment(rs); int receives; const char* receiver_name; - f3_set_d3(sundir_f, rs->start.sundir); - f3_mulf(seg->dir, sundir_f, -1); - CHECK(f3_is_normalized(seg->dir), 1); + d3_muld(seg->dir, rs->start.sundir, -1); + CHECK(d3_is_normalized(seg->dir), 1); S3D(primitive_get_attrib (&rs->start.primitive, S3D_GEOMETRY_NORMAL, rs->start.uv, &attrib)); CHECK(attrib.type, S3D_FLOAT3); /* fill fragment from starting point; must use sundir_f, not seg->dir */ - surface_fragment_setup(&rs->data.fragment, seg->org, sundir_f, attrib.value, - &rs->start.primitive, rs->start.uv); + surface_fragment_setup(&rs->data.fragment, seg->org, rs->start.sundir, + attrib.value, &rs->start.primitive, rs->start.uv); /* check normal orientation */ rs->start.cos_sun = d3_dot(rs->data.fragment.Ng, rs->start.sundir); if (rs->start.cos_sun >= 0) @@ -381,8 +390,8 @@ receive_sunlight(struct realisation* rs) /* check occlusion, avoiding self intersect */ seg->hit.prim = rs->start.primitive; /* TODO (in s3d): need an occlusion test */ - S3D(scene_view_trace_ray - (rs->data.view_rt, seg->org, seg->dir, seg->range, rs, &seg->hit)); + ASSERT(current_segment(rs) == sun_segment(rs)); + solstice_trace_ray(rs); receives = S3D_HIT_NONE(&seg->hit); if (!receives) return receives; @@ -398,7 +407,7 @@ receive_sunlight(struct realisation* rs) rs->freq, seg->weight, SPLIT3(seg->org), - SPLIT3(sundir_f), + SPLIT3(seg->dir), SPLIT2(rs->start.uv)); } @@ -418,7 +427,6 @@ set_output_pos_and_dir(struct realisation* rs) { struct segment* seg = current_segment(rs); struct segment* prev = previous_segment(rs); struct ssol_scene* scene = rs->data.scene; - float tmp[3]; int fst_segment; res_T res = RES_OK; @@ -428,10 +436,10 @@ set_output_pos_and_dir(struct realisation* rs) { fst_segment = (prev == sun_segment(rs)); if (fst_segment) { - f3_set(seg->org, prev->org); + d3_set(seg->org, prev->org); material = rs->start.material; } else { - f3_set(seg->org, prev->hit_pos); + d3_set(seg->org, prev->hit_pos); material = get_material_from_hit(scene, &prev->hit); } CHECK(material->type, MATERIAL_MIRROR); @@ -440,19 +448,18 @@ set_output_pos_and_dir(struct realisation* rs) { rs->end = TERM_ERR; return res; } - f3_set_d3(tmp, rs->data.fragment.Ns); if (fst_segment) { - float sundir_f[3]; const struct ssol_sun* sun = rs->data.scene->sun; ASSERT(-1 <= rs->start.cos_sun && rs->start.cos_sun <= 0); - f3_set_d3(sundir_f, rs->start.sundir); seg->weight = sun_get_dni(sun) - * brdf_composite_sample(rs->data.brdfs, rs->data.rng, sundir_f, tmp, seg->dir) + * brdf_composite_sample + (rs->data.brdfs, rs->data.rng, rs->start.sundir, rs->data.fragment.Ns, seg->dir) * -rs->start.cos_sun; } else { seg->weight = prev->weight * - brdf_composite_sample(rs->data.brdfs, rs->data.rng, prev->dir, tmp, seg->dir); + brdf_composite_sample + (rs->data.brdfs, rs->data.rng, prev->dir, rs->data.fragment.Ns, seg->dir); } return res; } @@ -463,8 +470,7 @@ propagate(struct realisation* rs) struct segment* seg = current_segment(rs); /* check if the ray hits something */ - S3D(scene_view_trace_ray - (rs->data.view_rt, seg->org, seg->dir, seg->range, rs, &seg->hit)); + solstice_trace_ray(rs); if (S3D_HIT_NONE(&seg->hit)) { rs->end = TERM_MISSING; return; @@ -488,8 +494,8 @@ propagate(struct realisation* rs) } /* fill fragment from hit and loop */ - f3_mulf(seg->hit_pos, seg->dir, seg->hit.distance); - f3_add(seg->hit_pos, seg->org, seg->hit_pos); + d3_muld(seg->hit_pos, seg->dir, (double)seg->hit.distance); + d3_add(seg->hit_pos, seg->org, seg->hit_pos); surface_fragment_setup(&rs->data.fragment, seg->hit_pos, seg->dir, seg->hit.normal, &seg->hit.prim, seg->hit.uv); } diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h @@ -60,9 +60,8 @@ struct segment { double weight; float range[2]; struct s3d_hit hit; - /* TODO: use double? */ - float org[3], dir[4]; - float hit_pos[3]; + double org[3], dir[4]; + double hit_pos[3]; }; struct starting_point {