commit a50229a187661b8ce263d5f1e3eff720bd6be5db
parent d74054cf855ab88d073e21386b0126c2d9f64d9c
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 5 Sep 2016 16:26:59 +0200
Use double for some struct fields.
Keep org, dir and hit_pos in double for in solver's raytracing segments.
Modify various functions accordingly.
Diffstat:
8 files changed, 58 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
@@ -63,8 +63,8 @@ material_get_type(const struct ssol_material* mtl)
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_solver.c b/src/ssol_solver.c
@@ -61,6 +61,15 @@ get_3dscene(const struct ssol_object_instance* instance)
return instance->object->s3d_scn;
}
+static INLINE 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.trace_view, org, dir, seg->range, rs, &seg->hit));
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -381,7 +390,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;
@@ -413,21 +422,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)
@@ -435,8 +442,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.trace_view, 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;
@@ -452,7 +459,7 @@ receive_sunlight(struct realisation* rs)
rs->freq,
seg->weight,
SPLIT3(seg->org),
- SPLIT3(sundir_f),
+ SPLIT3(seg->dir),
SPLIT2(rs->start.uv));
}
@@ -472,7 +479,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;
@@ -482,10 +488,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_get_type(material), MATERIAL_MIRROR);
@@ -494,19 +500,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 = scene_get_sun(rs->data.scene);
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;
}
@@ -517,8 +522,8 @@ propagate(struct realisation* rs)
struct segment* seg = current_segment(rs);
/* check if the ray hits something */
- S3D(scene_view_trace_ray
- (rs->data.trace_view, seg->org, seg->dir, seg->range, rs, &seg->hit));
+
+ solstice_trace_ray(rs);
if (S3D_HIT_NONE(&seg->hit)) {
rs->end = TERM_MISSING;
return;
@@ -542,8 +547,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 {