solstice-solver

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

commit 233b99fa91f1ecaf6ee6748ad9462064663a1083
parent 8ce2024b7c880c7e55353f173e3d56b911c98797
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 14 Dec 2016 16:58:03 +0100

Add and test the matte material

Diffstat:
Msrc/ssol.h | 21++++++++++++++++++++-
Msrc/ssol_material.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/ssol_material_c.h | 4+++-
Msrc/test_ssol_material.c | 52++++++++++++++++++++++++++++++++++++----------------
4 files changed, 135 insertions(+), 28 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -199,7 +199,7 @@ typedef void const double w[3], /* Incoming direction. Point toward the surface */ double* val); /* Returned value */ -/* Material descriptors */ +/* Mirror material shader */ struct ssol_mirror_shader { ssol_shader_getter_T normal; ssol_shader_getter_T reflectivity; @@ -209,6 +209,15 @@ struct ssol_mirror_shader { static const struct ssol_mirror_shader SSOL_MIRROR_SHADER_NULL = SSOL_MIRROR_SHADER_NULL__; +/* Matte material shader */ +struct ssol_matte_shader { + ssol_shader_getter_T normal; + ssol_shader_getter_T reflectivity; +}; +#define SSOL_MATTE_SHADER_NULL__ { NULL, NULL } +static const struct ssol_matte_shader SSOL_MATTE_SHADER_NULL = + SSOL_MATTE_SHADER_NULL__; + /* The type of data produced on receiver hits as ssol_solve() write them on its * FILE* argument */ struct ssol_receiver_data { @@ -480,6 +489,11 @@ ssol_material_create_mirror struct ssol_material** mtl); SSOL_API res_T +ssol_material_create_matte + (struct ssol_device* dev, + struct ssol_material** mtl); + +SSOL_API res_T ssol_material_create_virtual (struct ssol_device* dev, struct ssol_material** mtl); @@ -502,6 +516,11 @@ ssol_mirror_set_shader (struct ssol_material* mtl, const struct ssol_mirror_shader* shader); +SSOL_API res_T +ssol_matte_set_shader + (struct ssol_material* mtl, + const struct ssol_matte_shader* shader); + /******************************************************************************* * Object API - Opaque abstraction of a geometry with its associated properties. ******************************************************************************/ diff --git a/src/ssol_material.c b/src/ssol_material.c @@ -34,6 +34,46 @@ * Helper functions ******************************************************************************/ static res_T +matte_shade + (const struct ssol_material* mtl, + const struct surface_fragment* fragment, + const double wavelength, /* In nanometer */ + struct ssf_bsdf* bsdf) +{ + struct ssf_bxdf* brdf = NULL; + const struct ssol_matte_shader* shader; + double normal[3]; + double reflectivity; + res_T res; + ASSERT(mtl && fragment && mtl->type == MATERIAL_MATTE); + ASSERT(bsdf); + + shader = &mtl->data.matte; + + /* Fetch material attribs */ + shader->normal(mtl->dev, mtl->buf, wavelength, fragment->pos, + fragment->Ng, fragment->Ns, fragment->uv, fragment->dir, normal); + shader->reflectivity(mtl->dev, mtl->buf, wavelength, fragment->pos, + fragment->Ng, fragment->Ns, fragment->uv, fragment->dir, &reflectivity); + + /* Setup the BRDF */ + res = ssf_bxdf_create(mtl->dev->allocator, &ssf_lambertian_reflection, &brdf); + if(res != RES_OK) goto error; + res = ssf_lambertian_reflection_setup(brdf, reflectivity); + if(res != RES_OK) goto error; + + /* Setup the BSDF */ + res = ssf_bsdf_add(bsdf, brdf, 1.0); + if(res != RES_OK) goto error; + +exit: + if(brdf) SSF(bxdf_ref_put(brdf)); + return res; +error: + goto exit; +} + +static res_T mirror_shade (const struct ssol_material* mtl, const struct surface_fragment* fragment, @@ -113,15 +153,21 @@ material_release(ref_T* ref) SSOL(device_ref_put(dev)); } -static INLINE res_T -shader_ok(const struct ssol_mirror_shader* shader) +static INLINE int +check_shader_mirror(const struct ssol_mirror_shader* shader) { - if(!shader - || !shader->normal - || !shader->reflectivity - || !shader->roughness) - return RES_BAD_ARG; - return RES_OK; + return shader + && shader->normal + && shader->reflectivity + && shader->roughness; +} + +static INLINE int +check_shader_matte(const struct ssol_matte_shader* shader) +{ + return shader + && shader->normal + && shader->reflectivity; } /******************************************************************************* @@ -205,16 +251,33 @@ ssol_material_create_mirror } res_T +ssol_material_create_matte + (struct ssol_device* dev, struct ssol_material** out_material) +{ + return ssol_material_create(dev, out_material, MATERIAL_MATTE); +} + +res_T ssol_mirror_set_shader (struct ssol_material* material, const struct ssol_mirror_shader* shader) { if(!material || material->type != MATERIAL_MIRROR - || shader_ok(shader) != RES_OK) + || !check_shader_mirror(shader)) return RES_BAD_ARG; - material->data.mirror = *shader; + return RES_OK; +} +res_T +ssol_matte_set_shader + (struct ssol_material* material, const struct ssol_matte_shader* shader) +{ + if(!material + || material->type != MATERIAL_MATTE + || !check_shader_matte(shader)) + return RES_BAD_ARG; + material->data.matte = *shader; return RES_OK; } @@ -302,6 +365,9 @@ material_shade /* Specific material shading */ switch(mtl->type) { + case MATERIAL_MATTE: + res = matte_shade(mtl, fragment, wavelength, bsdf); + break; case MATERIAL_MIRROR: res = mirror_shade(mtl, fragment, wavelength, bsdf); break; diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h @@ -35,8 +35,9 @@ static const struct surface_fragment SURFACE_FRAGMENT_NULL = SURFACE_FRAGMENT_NULL__; enum material_type { - MATERIAL_VIRTUAL, + MATERIAL_MATTE, MATERIAL_MIRROR, + MATERIAL_VIRTUAL, MATERIAL_TYPES_COUNT__ }; @@ -44,6 +45,7 @@ struct ssol_material { enum material_type type; union { + struct ssol_matte_shader matte; struct ssol_mirror_shader mirror; } data; diff --git a/src/test_ssol_material.c b/src/test_ssol_material.c @@ -26,7 +26,8 @@ main(int argc, char** argv) struct mem_allocator allocator; struct ssol_device* dev; struct ssol_material* material; - struct ssol_mirror_shader shader = SSOL_MIRROR_SHADER_NULL; + struct ssol_mirror_shader mirror = SSOL_MIRROR_SHADER_NULL; + struct ssol_matte_shader matte = SSOL_MATTE_SHADER_NULL; struct ssol_param_buffer* pbuf = NULL; (void) argc, (void) argv; @@ -52,31 +53,31 @@ main(int argc, char** argv) CHECK(ssol_param_buffer_create(dev, 32, &pbuf), RES_OK); - shader.normal = get_shader_normal; - shader.reflectivity = get_shader_reflectivity; - shader.roughness = get_shader_roughness; + mirror.normal = get_shader_normal; + mirror.reflectivity = get_shader_reflectivity; + mirror.roughness = get_shader_roughness; - CHECK(ssol_mirror_set_shader(NULL, &shader), RES_BAD_ARG); + CHECK(ssol_mirror_set_shader(NULL, &mirror), RES_BAD_ARG); CHECK(ssol_mirror_set_shader(material, NULL), RES_BAD_ARG); - CHECK(ssol_mirror_set_shader(material, &shader), RES_OK); - CHECK(ssol_mirror_set_shader(material, &shader), RES_OK); + CHECK(ssol_mirror_set_shader(material, &mirror), RES_OK); + CHECK(ssol_mirror_set_shader(material, &mirror), RES_OK); CHECK(ssol_material_set_param_buffer(NULL, NULL), RES_BAD_ARG); CHECK(ssol_material_set_param_buffer(material, NULL), RES_BAD_ARG); CHECK(ssol_material_set_param_buffer(NULL, pbuf), RES_BAD_ARG); CHECK(ssol_material_set_param_buffer(material, pbuf), RES_OK); - shader.normal = NULL; - CHECK(ssol_mirror_set_shader(material, &shader), RES_BAD_ARG); - shader.normal = get_shader_normal; + mirror.normal = NULL; + CHECK(ssol_mirror_set_shader(material, &mirror), RES_BAD_ARG); + mirror.normal = get_shader_normal; - shader.reflectivity = NULL; - CHECK(ssol_mirror_set_shader(material, &shader), RES_BAD_ARG); - shader.reflectivity = get_shader_reflectivity; + mirror.reflectivity = NULL; + CHECK(ssol_mirror_set_shader(material, &mirror), RES_BAD_ARG); + mirror.reflectivity = get_shader_reflectivity; - shader.roughness = NULL; - CHECK(ssol_mirror_set_shader(material, &shader), RES_BAD_ARG); - shader.roughness = get_shader_roughness; + mirror.roughness = NULL; + CHECK(ssol_mirror_set_shader(material, &mirror), RES_BAD_ARG); + mirror.roughness = get_shader_roughness; CHECK(ssol_material_ref_put(material), RES_OK); @@ -87,6 +88,25 @@ main(int argc, char** argv) CHECK(ssol_material_ref_put(material), RES_OK); CHECK(ssol_param_buffer_ref_put(pbuf), RES_OK); + CHECK(ssol_material_create_matte(NULL, NULL), RES_BAD_ARG); + CHECK(ssol_material_create_matte(dev, NULL), RES_BAD_ARG); + CHECK(ssol_material_create_matte(NULL, &material), RES_BAD_ARG); + CHECK(ssol_material_create_matte(dev, &material), RES_OK); + + matte.normal = get_shader_normal; + matte.reflectivity = get_shader_reflectivity; + CHECK(ssol_matte_set_shader(NULL, NULL), RES_BAD_ARG); + CHECK(ssol_matte_set_shader(material, NULL), RES_BAD_ARG); + CHECK(ssol_matte_set_shader(NULL, &matte), RES_BAD_ARG); + CHECK(ssol_matte_set_shader(material, &matte), RES_OK); + + matte.normal = NULL; + CHECK(ssol_matte_set_shader(material, &matte), RES_BAD_ARG); + matte.normal = get_shader_normal; + matte.reflectivity = NULL; + CHECK(ssol_matte_set_shader(material, &matte), RES_BAD_ARG); + + CHECK(ssol_material_ref_put(material), RES_OK); CHECK(ssol_device_ref_put(dev), RES_OK); logger_release(&logger);