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:
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;