star-sf

Set of surface and volume scattering functions
git clone git://git.meso-star.fr/star-sf.git
Log | Files | Refs | README | LICENSE

commit 684db093a056512c9f6bdb1e8b4f9c6adcd06b91
parent 1e0e4d12a0e75a61acb906957fdebc670e82fe48
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu,  8 Sep 2016 15:10:23 +0200

Implement the generic ssf_fresnel API

Diffstat:
Mcmake/CMakeLists.txt | 7+++++--
Msrc/ssf.h | 48+++++++++++++++++++++++++++++++++++++++++++-----
Asrc/ssf_fresnel.c | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ssf_fresnel_c.h | 34++++++++++++++++++++++++++++++++++
4 files changed, 203 insertions(+), 7 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -45,10 +45,13 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SSF_FILES_DOC COPYING README.md) set(SSF_FILES_INC_API ssf.h) -set(SSF_FILES_INC ssf_bxdf_c.h) -set(SSF_FILES_SRC +set(SSF_FILES_INC + ssf_bxdf_c.h + ssf_fresnel_c.h) +set(SSF_FILES_SRC ssf_bsdf.c ssf_bxdf.c + ssf_fresnel.c ssf_specular_reflection.c) rcmake_prepend_path(SSF_FILES_SRC ${SSF_SOURCE_DIR}) rcmake_prepend_path(SSF_FILES_INC ${SSF_SOURCE_DIR}) diff --git a/src/ssf.h b/src/ssf.h @@ -41,6 +41,7 @@ struct mem_allocator; /* Opaque data types */ struct ssf_bsdf; /* Bidirectional Scattering Distribution Function */ struct ssf_bxdf; /* Bidirectional <Reflec|Transmit>tance Distribution Function */ +struct ssf_fresnel; /* Equation of the Fresnel term */ /* Generic BxDF type descriptor */ struct ssf_bxdf_type { @@ -60,6 +61,20 @@ struct ssf_bxdf_type { size_t alignof_bxdf; /* In Bytes */ }; +/* Generic Fresnel term descriptor */ +struct ssf_fresnel_type { + res_T (*init)(struct mem_allocator* allocator, void* fresnel); + void (*release)(void* bxdf); + + double + (*eval) + (void* fresnel, + const double cos_theta); /* Cosine between facet normal and outgoing dir */ + + size_t sizeof_fresnel; /* In Bytes */ + size_t alignof_fresnel; /* In Bytes */ +}; + BEGIN_DECLS /* Reflects the incoming direction with respect to the surface normal */ @@ -102,6 +117,29 @@ ssf_bsdf_sample double* radiance); /* Sampled radiance */ /******************************************************************************* + * Fresnel API - Define the equation of the fresnel term + ******************************************************************************/ +SSF_API res_T +ssf_fresnel_create + (struct mem_allocator* allocator, + const struct ssf_fresnel_type* type, + struct ssf_fresnel** fresnel); + +SSF_API res_T +ssf_fresnel_ref_get + (struct ssf_fresnel* fresnel); + +SSF_API res_T +ssf_fresnel_ref_put + (struct ssf_fresnel* fresnel); + +SSF_API res_T +ssf_fresnel_eval + (struct ssf_fresnel* fresnel, + const double cos_theta, /* Cos between facet normal and outgoing dir */ + double* value); + +/******************************************************************************* * BxDF API - Bidirecitonal <Reflectance|Transmittance> distribution function. * Describes how the light is reflected|transmitted by a surface. ******************************************************************************/ @@ -129,11 +167,6 @@ ssf_bxdf_sample double dir[4], /* Sampled direction. The PDF is stored in dir[3] */ double* radiance); /* Sampled radiance */ -SSF_API res_T -ssf_specular_reflection_setup - (struct ssf_bxdf* bxdf, - const double reflectivity); - /* Retrieve the internal data of the BxDF. Usefull for user defined BxDF on * which the caller has to retrieve them to setup the its parameters */ SSF_API res_T @@ -141,6 +174,11 @@ ssf_bxdf_get_data (struct ssf_bxdf* bxdf, void** data); +SSF_API res_T +ssf_specular_reflection_setup + (struct ssf_bxdf* bxdf, + const double reflectivity); + END_DECLS #endif /* SSF_H */ diff --git a/src/ssf_fresnel.c b/src/ssf_fresnel.c @@ -0,0 +1,121 @@ +/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com) + * + * 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 "ssf_fresnel_c.h" + +#include <rsys/math.h> +#include <rsys/mem_allocator.h> + +#include <string.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE int +check_fresnel_type(const struct ssf_fresnel_type* type) +{ + return type + && type->init + && type->release + && type->eval + && IS_POW2(type->alignof_fresnel); +} + +static void +fresnel_release(ref_T* ref) +{ + struct ssf_fresnel* fresnel = CONTAINER_OF(ref, struct ssf_fresnel, ref); + ASSERT(ref); + if(fresnel->data) { + fresnel->type.release(fresnel->data); + MEM_RM(fresnel->allocator, fresnel->data); + } + MEM_RM(fresnel->allocator, fresnel); +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +ssf_fresnel_create + (struct mem_allocator* allocator, + const struct ssf_fresnel_type* type, + struct ssf_fresnel** out_fresnel) +{ + struct mem_allocator* mem_allocator; + struct ssf_fresnel* fresnel = NULL; + res_T res = RES_OK; + + if(!out_fresnel || !check_fresnel_type(type)) { + res = RES_BAD_ARG; + goto error; + } + + mem_allocator = allocator ? allocator : &mem_default_allocator; + fresnel = MEM_CALLOC(mem_allocator, 1, sizeof(struct ssf_fresnel)); + if(!fresnel) { + res = RES_MEM_ERR; + goto error; + } + ref_init(&fresnel->ref); + fresnel->allocator = mem_allocator; + fresnel->type = *type; + + fresnel->data = MEM_ALLOC_ALIGNED(fresnel->allocator, + fresnel->type.sizeof_fresnel, fresnel->type.alignof_fresnel); + if(!fresnel->data) { + res = RES_MEM_ERR; + goto error; + } + memset(fresnel->data, 0, fresnel->type.sizeof_fresnel); + res = fresnel->type.init(fresnel->allocator, fresnel->data); + if(res != RES_OK) goto error; + +exit: + if(out_fresnel) *out_fresnel = fresnel; + return res; +error: + if(fresnel) { + SSF(fresnel_ref_put(fresnel)); + fresnel = NULL; + } + goto exit; +} + +res_T +ssf_fresnel_ref_get(struct ssf_fresnel* fresnel) +{ + if(!fresnel) return RES_BAD_ARG; + ref_get(&fresnel->ref); + return RES_OK; +} + +res_T +ssf_fresnel_ref_put(struct ssf_fresnel* fresnel) +{ + if(!fresnel) return RES_BAD_ARG; + ref_put(&fresnel->ref, fresnel_release); + return RES_OK; +} + +res_T +ssf_fresnel_eval + (struct ssf_fresnel* fresnel, const double cos_theta, double* val) +{ + if(!fresnel || cos_theta < 0.0) return RES_BAD_ARG; + *val = fresnel->type.eval(fresnel->data, cos_theta); + return RES_OK; +} + diff --git a/src/ssf_fresnel_c.h b/src/ssf_fresnel_c.h @@ -0,0 +1,34 @@ +/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com) + * + * 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 SSF_FRESNEL_C_H +#define SSF_FRESNEL_C_H + +#include "ssf.h" +#include <rsys/ref_count.h> + +struct mem_allocator; + +struct ssf_fresnel { + struct ssf_fresnel_type type; + void* data; /* Specific internal data of the Fresnel term */ + + /* Private data */ + ref_T ref; + struct mem_allocator* allocator; +}; + +#endif /* SSF_FRESNEL_C_H */ +