solstice-solver

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

commit 0167ffad7c5c26a242cc51461622f1042ec0d41a
parent 908e175886f6beffac3f94e0bc27bee108c86dab
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  5 Oct 2016 12:08:04 +0200

Use Star-SF library rather than internal BRDFs

Diffstat:
Mcmake/CMakeLists.txt | 12++++--------
Dsrc/ssol_brdf.c | 89-------------------------------------------------------------------------------
Dsrc/ssol_brdf.h | 57---------------------------------------------------------
Dsrc/ssol_brdf_composite.c | 173-------------------------------------------------------------------------------
Dsrc/ssol_brdf_composite.h | 59-----------------------------------------------------------
Dsrc/ssol_brdf_reflection.c | 93-------------------------------------------------------------------------------
Dsrc/ssol_brdf_reflection.h | 32--------------------------------
Msrc/ssol_material.c | 62+++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/ssol_material_c.h | 6+++---
Msrc/ssol_solver.c | 31++++++++++++++++++++-----------
Msrc/ssol_solver_c.h | 2+-
11 files changed, 75 insertions(+), 541 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -27,6 +27,7 @@ find_package(RCMake 0.2.3 REQUIRED) find_package(RSys 0.3 REQUIRED) find_package(Star3D 0.4 REQUIRED) find_package(StarCPR REQUIRED) +find_package(StarSF 0.0 REQUIRED) find_package(StarSP 0.4 REQUIRED) find_package(OpenMP 1.2 REQUIRED) @@ -38,9 +39,10 @@ include_directories( ${RSys_INCLUDE_DIR} ${Star3D_INCLUDE_DIR} ${StarCPR_INCLUDE_DIR} + ${StarSF_INCLUDE_DIR} ${StarSP_INCLUDE_DIR}) -rcmake_append_runtime_dirs(_runtime_dirs RSys Star3D StarCPR StarSP) +rcmake_append_runtime_dirs(_runtime_dirs RSys Star3D StarCPR StarSF StarSP) ################################################################################ # Configure and define targets @@ -52,9 +54,6 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SSOL_FILES_SRC ssol_atmosphere.c - ssol_brdf.c - ssol_brdf_composite.c - ssol_brdf_reflection.c ssol_device.c ssol_image.c ssol_material.c @@ -73,9 +72,6 @@ set(SSOL_FILES_INC_API set(SSOL_FILES_INC ssol_atmosphere_c.h - ssol_brdf.h - ssol_brdf_composite.h - ssol_brdf_reflection.h ssol_c.h ssol_device_c.h ssol_image_c.h @@ -99,7 +95,7 @@ rcmake_prepend_path(SSOL_FILES_INC_API ${SSOL_SOURCE_DIR}) rcmake_prepend_path(SSOL_FILES_DOC ${PROJECT_SOURCE_DIR}/../) add_library(solstice-solver SHARED ${SSOL_FILES_SRC} ${SSOL_FILES_INC} ${SSOL_FILES_INC_API}) -target_link_libraries(solstice-solver RSys Star3D StarCPR StarSP) +target_link_libraries(solstice-solver RSys Star3D StarCPR StarSF StarSP) if(CMAKE_COMPILER_IS_GNUCC) target_link_libraries(solstice-solver m) diff --git a/src/ssol_brdf.c b/src/ssol_brdf.c @@ -1,89 +0,0 @@ -/* Copyright (C) CNRS 2016 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "ssol.h" -#include "ssol_brdf.h" -#include "ssol_device_c.h" - -#include <rsys/mem_allocator.h> - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static void -brdf_release(ref_T* ref) -{ - struct ssol_device* dev; - struct brdf* brdf = CONTAINER_OF(ref, struct brdf, ref); - ASSERT(ref); - dev = brdf->dev; - if(brdf->data) MEM_RM(dev->allocator, brdf->data); - MEM_RM(dev->allocator, brdf); - SSOL(device_ref_put(dev)); -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -brdf_create - (struct ssol_device* dev, const size_t sizeof_data, struct brdf** out_brdf) -{ - struct brdf* brdf = NULL; - res_T res = RES_OK; - ASSERT(dev && out_brdf); - - brdf = MEM_CALLOC(dev->allocator, 1, sizeof(struct brdf)); - if(!brdf) { - res = RES_MEM_ERR; - goto error; - } - ref_init(&brdf->ref); - SSOL(device_ref_get(dev)); - brdf->dev = dev; - - if(sizeof_data) { - brdf->data = MEM_CALLOC(dev->allocator, 1, sizeof_data); - if(!brdf->data) { - res = RES_MEM_ERR; - goto error; - } - } - -exit: - *out_brdf = brdf; - return res; -error: - if(brdf) { - brdf_ref_put(brdf); - brdf = NULL; - } - goto exit; -} - -void -brdf_ref_get(struct brdf* brdf) -{ - ASSERT(brdf); - ref_get(&brdf->ref); -} - -void -brdf_ref_put(struct brdf* brdf) -{ - ASSERT(brdf); - ref_put(&brdf->ref, brdf_release); -} - diff --git a/src/ssol_brdf.h b/src/ssol_brdf.h @@ -1,57 +0,0 @@ -/* Copyright (C) CNRS 2016 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef SSOL_BRDF_H -#define SSOL_BRDF_H - -#include <rsys/ref_count.h> - -struct ssp_rng; - -typedef double /* Sampled radiance */ -(*brdf_sample_func_T) - (void* data, /* BRDF internal data */ - struct ssp_rng* rng, /* Random Number Generator */ - 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 { - brdf_sample_func_T sample; - void* data; /* Specific internal data of the BRDF */ - - /* Private data */ - ref_T ref; - struct ssol_device* dev; -}; - -/* Generic BRDF creation function */ -extern LOCAL_SYM res_T -brdf_create - (struct ssol_device* dev, - const size_t sizeof_data, - struct brdf** brdf); - -extern LOCAL_SYM void -brdf_ref_get - (struct brdf* brdf); - -extern LOCAL_SYM void -brdf_ref_put - (struct brdf* brdf); - -#endif /* SSOL_BRDF_H */ - diff --git a/src/ssol_brdf_composite.c b/src/ssol_brdf_composite.c @@ -1,173 +0,0 @@ -/* Copyright (C) CNRS 2016 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "ssol.h" -#include "ssol_brdf.h" -#include "ssol_brdf_composite.h" -#include "ssol_device_c.h" - -#include <rsys/dynamic_array.h> -#include <rsys/double4.h> -#include <rsys/ref_count.h> - -#include <star/ssp.h> - -#define MAX_COMPONENTS 8 - -struct brdf_composite { - struct brdf* components[MAX_COMPONENTS]; - size_t ncomponents; - - ref_T ref; - struct ssol_device* dev; -}; - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static void -brdf_composite_release(ref_T* ref) -{ - struct ssol_device* dev; - struct brdf_composite* brdfs = CONTAINER_OF(ref, struct brdf_composite, ref); - ASSERT(ref); - - brdf_composite_clear(brdfs); - dev = brdfs->dev; - MEM_RM(dev->allocator, brdfs); - SSOL(device_ref_put(dev)); -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -brdf_composite_create - (struct ssol_device* dev, struct brdf_composite** out_brdfs) -{ - struct brdf_composite* brdfs = NULL; - res_T res = RES_OK; - ASSERT(dev && out_brdfs); - - brdfs = MEM_CALLOC(dev->allocator, 1, sizeof(struct brdf_composite)); - if(!brdfs) { - res = RES_MEM_ERR; - goto error; - } - - ref_init(&brdfs->ref); - SSOL(device_ref_get(dev)); - brdfs->dev = dev; - -exit: - *out_brdfs = brdfs; - return res; -error: - if(brdfs) { - brdf_composite_ref_put(brdfs); - brdfs = NULL; - } - goto exit; -} - -void -brdf_composite_ref_get(struct brdf_composite* brdfs) -{ - ASSERT(brdfs); - ref_get(&brdfs->ref); -} - -void -brdf_composite_ref_put(struct brdf_composite* brdfs) -{ - ASSERT(brdfs); - ref_put(&brdfs->ref, brdf_composite_release); -} - -res_T -brdf_composite_add(struct brdf_composite* brdfs, struct brdf* brdf) -{ - ASSERT(brdfs && brdf); - if(brdfs->ncomponents >= MAX_COMPONENTS) return RES_MEM_ERR; - brdf_ref_get(brdf); - brdfs->components[brdfs->ncomponents] = brdf; - ++brdfs->ncomponents; - return RES_OK; -} - -void -brdf_composite_clear(struct brdf_composite* brdfs) -{ - size_t i; - ASSERT(brdfs); - FOR_EACH(i, 0, brdfs->ncomponents) { - brdf_ref_put(brdfs->components[i]); - } - brdfs->ncomponents = 0; -} - -double -brdf_composite_sample - (struct brdf_composite* brdfs, - struct ssp_rng* rng, - const double w[3], - const double N[3], - double dir[4]) -{ - const size_t PDF = 3; - double radiances[MAX_COMPONENTS]; - double dirs[MAX_COMPONENTS][4]; - double probas[MAX_COMPONENTS]; - double cumul[MAX_COMPONENTS]; - double probas_sum; - double r; - size_t i, n; - ASSERT(brdfs && rng && w && N && dir); - - /* Build the probability distribution by sampling each BRDF */ - n = 0; - probas_sum = 0.0f; - FOR_EACH(i, 0, brdfs->ncomponents) { - struct brdf* brdf = brdfs->components[i]; - - radiances[n] = brdf->sample(brdf->data, rng, w, N, dirs[n]); - if(radiances[n] <= 0 || dirs[n][PDF] <= 0) - continue; /* Discard component */ - - probas[n] = radiances[n] / dirs[n][PDF]; - probas_sum += probas[n]; - ++n; - } - - if(!n) { /* No valid component to sample */ - d4_splat(dir, 0); - return 0; - } - - /* Normalize the probability distribution */ - FOR_EACH(i, 0, n) probas[i] /= probas_sum; - - /* Compute the cumulative */ - cumul[0] = probas[0]; - cumul[n-1] = 1.f; - FOR_EACH(i, 1, n-1) cumul[i] = cumul[i-1] + probas[i]; - - /* Finally sample the distribution */ - r = ssp_rng_canonical(rng); - FOR_EACH(i, 0, n-1) if(r <= cumul[i]) break; - d4_set(dir, dirs[i]); - return radiances[i]; -} - diff --git a/src/ssol_brdf_composite.h b/src/ssol_brdf_composite.h @@ -1,59 +0,0 @@ -/* Copyright (C) CNRS 2016 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef SSOL_BRDF_COMPOSITE_H -#define SSOL_BRDF_COMPOSITE_H - -#include <rsys/rsys.h> - -struct brdf; -struct ssol_device; -struct ssp_rng; - -/* Container of BRDFs */ -struct brdf_composite; - -extern LOCAL_SYM res_T -brdf_composite_create - (struct ssol_device* dev, - struct brdf_composite** brdfs); - -extern LOCAL_SYM void -brdf_composite_ref_get - (struct brdf_composite* brdfs); - -extern LOCAL_SYM void -brdf_composite_ref_put - (struct brdf_composite* brdfs); - -extern LOCAL_SYM res_T -brdf_composite_add - (struct brdf_composite* brdfs, - struct brdf* brdf); - -extern LOCAL_SYM void -brdf_composite_clear - (struct brdf_composite* brdfs); - -extern LOCAL_SYM double -brdf_composite_sample - (struct brdf_composite* brdfs, - struct ssp_rng* rng, - 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 @@ -1,93 +0,0 @@ -/* Copyright (C) CNRS 2016 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "ssol_device_c.h" -#include "ssol_brdf_reflection.h" - -#include <rsys/double3.h> - -struct brdf_reflection { - double reflectivity; -}; - -/******************************************************************************* - * Helper function - ******************************************************************************/ -static double -reflection_sample - (void* data, - struct ssp_rng* rng, - const double w[3], - const double N[3], - double dir[4]) -{ - struct brdf_reflection* reflection = data; - double cosi; - (void)rng; - 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 = -d3_dot(w, N); - d3_muld(dir, N, 2*cosi); - d3_add(dir, dir, w); - dir[3] = 1; /* pdf */ - return reflection->reflectivity; -} - -/******************************************************************************* - * Local function - ******************************************************************************/ -res_T -brdf_reflection_create - (struct ssol_device* dev, - struct brdf** out_brdf) -{ - struct brdf* brdf = NULL; - struct brdf_reflection* reflection = NULL; - res_T res = RES_OK; - ASSERT(dev && out_brdf); - - res = brdf_create(dev, sizeof(struct brdf_reflection), &brdf); - if(res != RES_OK) goto error; - - brdf->sample = reflection_sample; - reflection = brdf->data; - reflection->reflectivity = 1.0; -exit: - *out_brdf = brdf; - return res; -error: - if(brdf) { - brdf_ref_put(brdf); - brdf = NULL; - } - goto exit; -} - -res_T -brdf_reflection_setup(struct brdf* brdf, const double reflectivity) -{ - struct brdf_reflection* reflection; - ASSERT(brdf); - reflection = brdf->data; - if(reflectivity < 0) { - log_error(brdf->dev, - "Invalid reflectivity `%g' for the reflection BRDF.\n", reflectivity); - return RES_BAD_ARG; - } - reflection->reflectivity = reflectivity; - return RES_OK; -} - diff --git a/src/ssol_brdf_reflection.h b/src/ssol_brdf_reflection.h @@ -1,32 +0,0 @@ -/* Copyright (C) CNRS 2016 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef SSOL_BRDF_REFLECTION_H -#define SSOL_BRDF_REFLECTION_H - -#include "ssol_brdf.h" - -extern LOCAL_SYM res_T -brdf_reflection_create - (struct ssol_device* dev, - struct brdf** brdf); - -extern LOCAL_SYM res_T -brdf_reflection_setup - (struct brdf* brdf, - const double reflectivity); - -#endif /* SSOL_BRDF_REFLECTION_H */ - diff --git a/src/ssol_material.c b/src/ssol_material.c @@ -14,8 +14,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "ssol.h" -#include "ssol_brdf_composite.h" -#include "ssol_brdf_reflection.h" #include "ssol_c.h" #include "ssol_material_c.h" #include "ssol_device_c.h" @@ -28,6 +26,8 @@ #include <rsys/rsys.h> #include <rsys/mem_allocator.h> +#include <star/ssf.h> + #include <math.h> /******************************************************************************* @@ -38,31 +38,63 @@ mirror_shade (const struct ssol_material* mtl, const struct surface_fragment* fragment, const double wavelength, /* In nanometer */ - struct brdf_composite* brdfs) + struct ssf_bsdf* bsdf) { - struct brdf* reflect = NULL; + struct ssf_bxdf* brdf = NULL; + struct ssf_fresnel* fresnel = NULL; + struct ssf_microfacet_distribution* distrib = NULL; const struct ssol_mirror_shader* shader; double normal[3]; - double R; /* Reflectivity */ + double roughness; + double reflectivity; res_T res; ASSERT(mtl && fragment && mtl->type == MATERIAL_MIRROR); - ASSERT(brdfs); + ASSERT(bsdf); shader = &mtl->data.mirror; - /* FIXME currently the mirror material is a purely reflective BRDF. Discard - * the roughness parameters */ + /* Fetch material attribs */ shader->normal(mtl->dev, wavelength, fragment->pos, fragment->Ng, fragment->Ns, fragment->uv, fragment->dir, normal); shader->reflectivity(mtl->dev, wavelength, fragment->pos, fragment->Ng, - fragment->Ns, fragment->uv, fragment->dir, &R); + fragment->Ns, fragment->uv, fragment->dir, &reflectivity); + shader->roughness(mtl->dev, wavelength, fragment->pos, fragment->Ng, + fragment->Ns, fragment->uv, fragment->dir, &roughness); + + /* Setup the fresnel term */ + res = ssf_fresnel_create(mtl->dev->allocator, &ssf_fresnel_constant, &fresnel); + if(res != RES_OK) goto error; + res = ssf_fresnel_constant_setup(fresnel, reflectivity); + if(res != RES_OK) goto error; + + /* Setup the BRDF */ + if(roughness == 0) { /* Purely specular reflection */ + res = ssf_bxdf_create(mtl->dev->allocator, &ssf_specular_reflection, &brdf); + if(res != RES_OK) goto error; + res = ssf_specular_reflection_setup(brdf, fresnel); + if(res != RES_OK) goto error; + } else { /* Glossy reflection */ + res = ssf_microfacet_distribution_create + (mtl->dev->allocator, &ssf_beckmann_distribution, &distrib); + if(res != RES_OK) goto error; + res = ssf_beckmann_distribution_setup(distrib, roughness); + if(res != RES_OK) goto error; + + res = ssf_bxdf_create + (mtl->dev->allocator, &ssf_microfacet2_reflection, &brdf); + if(res != RES_OK) goto error; + res = ssf_microfacet_reflection_setup(brdf, fresnel, distrib); + if(res != RES_OK) goto error; + } - if(RES_OK != (res = brdf_reflection_create(mtl->dev, &reflect))) goto error; - if(RES_OK != (res = brdf_reflection_setup(reflect, R))) goto error; - if(RES_OK != (res = brdf_composite_add(brdfs, reflect))) goto error; + /* Setup the BSDF */ + res = ssf_bsdf_add(bsdf, brdf, 1.0); + if(res != RES_OK) goto error; exit: - if(reflect) brdf_ref_put(reflect); + if(brdf) SSF(bxdf_ref_put(brdf)); + if(fresnel) SSF(fresnel_ref_put(fresnel)); + if(distrib) SSF(microfacet_distribution_ref_put(distrib)); return res; error: goto exit; @@ -252,7 +284,7 @@ material_shade (const struct ssol_material* mtl, const struct surface_fragment* fragment, const double wavelength, /* In nanometer */ - struct brdf_composite* brdfs) /* Container of BRDFs */ + struct ssf_bsdf* bsdf) { res_T res = RES_OK; ASSERT(mtl); @@ -260,7 +292,7 @@ material_shade /* Specific material shading */ switch(mtl->type) { case MATERIAL_MIRROR: - res = mirror_shade(mtl, fragment, wavelength, brdfs); + res = mirror_shade(mtl, fragment, wavelength, bsdf); break; case MATERIAL_VIRTUAL: /* Nothing to shade */ break; default: FATAL("Unreachable code\n"); break; diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h @@ -18,9 +18,9 @@ #include <rsys/ref_count.h> -struct brdf_composite; struct s3d_hit; struct s3d_primitive; +struct ssf_bsdf; struct ssol_device; struct surface_fragment { @@ -31,7 +31,7 @@ struct surface_fragment { double uv[2]; /* Texture coordinates */ }; #define SURFACE_FRAGMENT_NULL__ {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0}} -static const struct surface_fragment SURFACE_FRAGMENT_NULL = +static const struct surface_fragment SURFACE_FRAGMENT_NULL = SURFACE_FRAGMENT_NULL__; enum material_type { @@ -65,7 +65,7 @@ material_shade (const struct ssol_material* mtl, const struct surface_fragment* fragment, const double wavelength, /* In nanometer */ - struct brdf_composite* brdfs); /* Container of BRDFs */ + struct ssf_bsdf* bsdf); /* Bidirectional Scattering Distribution Function */ #endif /* SSOL_MATERIAL_C_H */ diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -25,7 +25,6 @@ #include "ssol_material_c.h" #include "ssol_spectrum_c.h" #include "ssol_instance_c.h" -#include "ssol_brdf_composite.h" #include "ssol_ranst_sun_dir.h" #include "ssol_ranst_sun_wl.h" @@ -36,6 +35,8 @@ #include <rsys/ref_count.h> #include <rsys/rsys.h> +#include <star/ssf.h> + #define END_TEXT__ \ { "NONE", "SUCCESS", "SHADOW", "POINTING", "MISSING", "BLOCKED", "ERROR" } @@ -179,7 +180,7 @@ release_solver_data(struct solver_data* data) if (data->view_samp) S3D(scene_view_ref_put(data->view_samp)); if (data->sun_dir_ran) CHECK(ranst_sun_dir_ref_put(data->sun_dir_ran), RES_OK); if (data->sun_wl_ran) CHECK(ranst_sun_wl_ref_put(data->sun_wl_ran), RES_OK); - if (data->brdfs) brdf_composite_ref_put(data->brdfs); + if (data->bsdf) SSF(bsdf_ref_put(data->bsdf)); if (data->receiver_record_candidates.data) darray_receiver_record_release(&data->receiver_record_candidates); if (data->instances_ptr.data) @@ -279,6 +280,9 @@ setup_next_segment(struct realisation* rs) res_T res = RES_OK; const struct segment* prev; const struct solver_data* data; + double wi[3]; /* Incident direction */ + double pdf; + double R; struct segment* seg; ASSERT(rs); @@ -302,20 +306,25 @@ setup_next_segment(struct realisation* rs) d3_set(seg->org, prev->hit_pos); - res = material_shade( - prev->hit_material, &data->fragment, rs->wavelength, data->brdfs); + res = material_shade + (prev->hit_material, &data->fragment, rs->wavelength, data->bsdf); if (res != RES_OK) { rs->end = TERM_ERR; return res; } - seg->weight = prev->weight - * brdf_composite_sample( - data->brdfs, data->rng, prev->dir, data->fragment.Ns, seg->dir); + /* By convention, Star-SF assumes that incoming and reflected directions + * point outward the surface => negate incoming dir */ + d3_minus(wi, prev->dir); + + R = ssf_bsdf_sample + (data->bsdf, data->rng, wi, data->fragment.Ns, seg->dir, &pdf); + seg->weight = prev->weight * R; + ASSERT(d3_dot(seg->dir, seg->dir)); if (rs->s_idx > 1) { - seg->weight *= compute_atmosphere_attenuation( - rs->data.scene->atmosphere, prev->hit_distance, rs->wavelength); + seg->weight *= compute_atmosphere_attenuation + (rs->data.scene->atmosphere, prev->hit_distance, rs->wavelength); } return res; @@ -393,7 +402,7 @@ reset_realisation(size_t cpt, struct realisation* rs) rs->rs_id = cpt; rs->success_mask = 0; reset_starting_point(&rs->start); - brdf_composite_clear(rs->data.brdfs); + SSF(bsdf_clear(rs->data.bsdf)); /* reset first segment (always used) */ reset_segment(current_segment(rs)); /* reset candidates */ @@ -431,7 +440,7 @@ init_realisation /* create sun distributions */ res = set_sun_distributions(&rs->data); if (res != RES_OK) goto error; - res = brdf_composite_create(scene->dev, &rs->data.brdfs); + res = ssf_bsdf_create(scene->dev->allocator, &rs->data.bsdf); if (res != RES_OK) goto error; exit: diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h @@ -123,7 +123,7 @@ struct solver_data { struct ranst_sun_dir* sun_dir_ran; struct ranst_sun_wl* sun_wl_ran; /* Tmp data used for propagation */ - struct brdf_composite* brdfs; + struct ssf_bsdf* bsdf; struct surface_fragment fragment; struct darray_receiver_record receiver_record_candidates; struct darray_instances_ptr instances_ptr;