commit 34fa20a0f072059f098580c4a8c0a38d6847fe1c
parent 2e9b98a63d2d7eaab762a53cd6d2e8e5d278e117
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 11 Sep 2015 16:17:33 +0200
Handle radiative paths that does not intersect a geometry
Their transmissivity is accumulated into the "environment". This value
is added the overall distributed transmissivity when the "energy
conservation" property is checked.
Diffstat:
| M | src/sgf.c | | | 54 | ++++++++++++++++++++---------------------------------- |
1 file changed, 20 insertions(+), 34 deletions(-)
diff --git a/src/sgf.c b/src/sgf.c
@@ -57,16 +57,16 @@ gebhart_radiative_path
{
struct s3d_hit hit;
struct sgf_accum* gebfac; /* Gebhart factor */
- struct s3d_primitive prim;
+ struct s3d_primitive prim_from, prim;
struct s3d_attrib attrib;
float st[2] = {0.f, 0.f};
+ double sky_gebhart = 0.0;
double transmissivity = 1.0;
double proba_reflec_spec;
double emissivity;
double reflectivity;
double specularity;
const double trans_min = 1.e-8;
- size_t iprim, iprim_from;
size_t nprims;
float vec0[3];
float normal[3];
@@ -99,42 +99,40 @@ gebhart_radiative_path
* `normal' */
ssp_ran_hemisphere_cos(rng, normal, dir);
- iprim = ctx->primitive_id;
transmissivity = 1.0;
+ sky_gebhart = 0.0;
for(;;) { /* Here we go */
- iprim_from = iprim;
+ prim_from = prim;
- range[0] = FLT_MIN, range[1] = FLT_MAX;
+ range[0] = 1.e-6f, range[1] = FLT_MAX;
for(;;) {
S3D(scene_trace_ray(ctx->scene, pos, dir, range, &hit));
- if(hit.prim.prim_id == iprim_from) range[0] += FLT_EPSILON; /* Self hit */
+ if(S3D_PRIMITIVE_EQ(&hit.prim, &prim_from)) range[0] += 1.e-6f; /* Self hit */
else break;
}
if(S3D_HIT_NONE(&hit)) {
- if(ctx->verbose) {
- logger_print(ctx->logger, LOG_OUTPUT, "Unexpected radiative path failure\n");
- return RES_BAD_OP;
- }
+ sky_gebhart += transmissivity;
+ break;
}
f3_normalize(normal, hit.normal);
/* Retrieve the hit position and the hit primitive id */
f3_mulf(vec0, dir, hit.distance);
f3_add(pos, vec0, pos);
- iprim = hit.prim.prim_id;
+ prim = hit.prim;
- /* Fetch material property */
+ /* Fetch material property. TODO fix the use of the prim_id */
emissivity = ctx->get_material_property
- (ctx->material, SGF_MATERIAL_EMISSIVITY, iprim, ispectral_band);
+ (ctx->material, SGF_MATERIAL_EMISSIVITY, prim.prim_id, ispectral_band);
specularity = ctx->get_material_property
- (ctx->material, SGF_MATERIAL_SPECULARITY, iprim, ispectral_band);
+ (ctx->material, SGF_MATERIAL_SPECULARITY, prim.prim_id, ispectral_band);
reflectivity = ctx->get_material_property
- (ctx->material, SGF_MATERIAL_REFLECTIVITY, iprim, ispectral_band);
+ (ctx->material, SGF_MATERIAL_REFLECTIVITY, prim.prim_id, ispectral_band);
- gebfac = result + iprim * ctx->spectral_bands_count;
+ gebfac = result + prim.prim_id * ctx->spectral_bands_count;
if(transmissivity > trans_min) {
const double weight = transmissivity * emissivity;
gebfac[ispectral_band].radiative_flux += weight;
@@ -169,11 +167,13 @@ gebhart_radiative_path
#if !defined(NDEBUG)
{ /* Ensure the energy conservation property */
double sum_radiative_flux = 0.0;
+ size_t iprim;
gebfac = result;
FOR_EACH(iprim, 0, nprims) {
sum_radiative_flux += gebfac[ispectral_band].radiative_flux;
gebfac += ctx->spectral_bands_count;
}
+ sum_radiative_flux += sky_gebhart;
ASSERT(eq_eps(sum_radiative_flux, 1.0, 1.e-6));
}
#endif
@@ -188,29 +188,15 @@ gebhart_factor_integrand
{
struct sgf_context* ctx = context;
struct sgf_accum* buf;
- size_t nfailures = 0;
size_t iband = 0;
- res_T res = RES_OK;
+ res_T res = RES_OK; (void)res;
ASSERT(result && rng && context);
buf = darray_gfacc_data_get(result);
FOR_EACH(iband, 0, ctx->spectral_bands_count) {
- do {
- accum_buffer_clear(result);
- res = gebhart_radiative_path(buf, rng, ctx, iband);
- } while(res == RES_BAD_OP && (++nfailures < MAX_FAILURES));
-
- if(ctx->verbose) {
- if(nfailures >= MAX_FAILURES) {
- logger_print(ctx->logger, LOG_ERROR,
-"Too many radiative path failures. The geometry might be wrongly setuped. The\n"
-"geometry should be closed and 2D-manifold. In addition its normals must point\n"
-"*into* the volume with respect to a Clock Wise vertex ordering\n");
- } else if(res != RES_OK) {
- logger_print(ctx->logger, LOG_ERROR,
- "Critical error in the computation of the Gebhart factor\n");
- }
- }
+ accum_buffer_clear(result);
+ res = gebhart_radiative_path(buf, rng, ctx, iband);
+ ASSERT(res == RES_OK);
}
}