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:
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 */
+