commit 8c9fd43c4ce8eb93bc12b018476b62b0fbc26aa2
parent b71f45d0999bccb403ad47582f9bd31bf04f0708
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 13 Jul 2016 10:06:25 +0200
Implement the BRDF interface & the reflection BRDF
Diffstat:
5 files changed, 276 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -49,6 +49,8 @@ set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SSOL_FILES_SRC
+ ssol_brdf.c
+ ssol_brdf_reflection.c
ssol_device.c
ssol_image.c
ssol_material.c
@@ -65,6 +67,8 @@ set(SSOL_FILES_INC_API
ssol.h)
set(SSOL_FILES_INC
+ ssol_brdf.h
+ ssol_brdf_reflection.h
ssol_device_c.h
ssol_image_c.h
ssol_material_c.h
diff --git a/src/ssol_brdf.c b/src/ssol_brdf.c
@@ -0,0 +1,89 @@
+/* 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_MEM_ERR;
+ 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
@@ -0,0 +1,57 @@
+/* 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 float w[3], /* Incoming direction. Point toward the surface */
+ const float N[3], /* Normalized normal */
+ float 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_reflection.c b/src/ssol_brdf_reflection.c
@@ -0,0 +1,94 @@
+/* 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/float3.h>
+
+struct brdf_reflection {
+ double reflectivity;
+};
+
+/*******************************************************************************
+ * Helper function
+ ******************************************************************************/
+static double
+reflection_sample
+ (void* data,
+ struct ssp_rng* rng,
+ const float w[3],
+ const float N[3],
+ float dir[4])
+{
+ struct brdf_reflection* reflection = data;
+ float vec[3], cosi;
+ (void)rng;
+ ASSERT(w && N && dir && f3_is_normalized(N) && f3_is_normalized(w) && data);
+
+ /* Simply reflect the incoming direction w[3] with respect to the normal */
+ f3_minus(vec, w);
+ cosi = f3_dot(vec, N);
+ f3_mulf(dir, N, cosi);
+ f3_sub(dir, vec, dir);
+ dir[3] = 1.f; /* 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;
+error:
+ *out_brdf = brdf;
+ return res;
+exit:
+ 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
@@ -0,0 +1,32 @@
+/* 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 */
+