commit 12012976ef1bb1b87d1df903b6b04317ee07490f
parent 385e7b8ece4d1cd4cbb095a7c7826419fcc12c60
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 20 Jul 2016 17:02:30 +0200
Write hit data if the hit instance is a receiver
Diffstat:
4 files changed, 88 insertions(+), 49 deletions(-)
diff --git a/src/ssol_c.h b/src/ssol_c.h
@@ -25,7 +25,12 @@
struct ray_data {
struct ssol_scene* scene; /* Scene in which the ray is traced */
- struct s3d_primitive prim_from; /* Primitive from which the scene start */
+ struct s3d_primitive prim_from; /* Primitive from which the ray starts */
+ unsigned path_id; /* Identifier of the path to which the ray belongs to */
+ unsigned ray_id; /* Identifier of the ray into the path */
+ double radiance; /* Current path radiance in W.sr^-1.m^-2 */
+ double wavelength; /* Wavelength of the current path in nanometer */
+ FILE* stream;
};
static FINLINE enum s3d_attrib_usage
diff --git a/src/ssol_material.c b/src/ssol_material.c
@@ -35,12 +35,8 @@
static res_T
mirror_shade
(const struct ssol_material* mtl,
+ const struct surface_fragment* fragment,
const double wavelength, /* In nanometer */
- const double P[3], /* World space position */
- const double Ng[3], /* World space geometry normal */
- const double Ns[3], /* World space shading normal */
- const double uv[2], /* Texture coordinates */
- const double w[3], /* Incoming direction. Point toward the surface */
struct brdf_composite* brdfs)
{
struct brdf* reflect = NULL;
@@ -48,14 +44,17 @@ mirror_shade
double normal[3];
double R; /* Reflectivity */
res_T res;
- ASSERT(mtl && P && Ng && Ns && uv && w && mtl->type == MATERIAL_MIRROR);
+ ASSERT(mtl && fragment && mtl->type == MATERIAL_MIRROR);
+ ASSERT(brdfs);
shader = &mtl->data.mirror;
/* FIXME currently the mirror material is a purely reflective BRDF. Discard
* the diffuse_specular_ratio & the rougness parameters */
- shader->normal(mtl->dev, wavelength, P, Ng, Ns, uv, w, normal);
- shader->reflectivity(mtl->dev, wavelength, P, Ng, Ns, uv, w, &R);
+ 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);
if(RES_OK != (res = brdf_reflection_create(mtl->dev, &reflect))) goto error;
if(RES_OK != (res = brdf_reflection_setup(reflect, R))) goto error;
@@ -189,59 +188,50 @@ ssol_material_create_virtual
/*******************************************************************************
* Local functions
******************************************************************************/
-res_T
-material_shade
- (const struct ssol_material* mtl,
- const double wavelength, /* In nanometer */
- const struct s3d_hit* hit, /* Hit point to shade */
- const float dir[3], /* Incoming direction */
- struct brdf_composite* brdfs) /* Container of BRDFs */
+void
+surface_fragment_setup
+ (struct surface_fragment* fragment,
+ const float ray_org[3],
+ const float ray_dir[3],
+ const struct s3d_hit* hit)
{
struct s3d_attrib attr;
- double w[3]; /* Incoming direction */
- double P[3]; /* World space hit position */
- double Ng[3]; /* World space normalized geometry normal */
- double Ns[3]; /* World space normalized shading normal */
- double uv[2]; /* Texture coordinates */
double len;
char has_texcoord, has_normal;
- res_T res = RES_OK;
- ASSERT(mtl && dir && hit && brdfs);
+ ASSERT(fragment && ray_org && ray_dir && hit);
- /* Convert the incoming direction in double */
- w[0] = (double)dir[0];
- w[1] = (double)dir[1];
- w[2] = (double)dir[2];
+ /* Setup the incoming direction */
+ fragment->dir[0] = ray_dir[0];
+ fragment->dir[1] = ray_dir[1];
+ fragment->dir[2] = ray_dir[2];
- /* Retrieve the hit position */
- S3D(primitive_get_attrib(&hit->prim, S3D_POSITION, hit->uv, &attr));
- ASSERT(attr.type == S3D_FLOAT3);
- P[0] = (double)attr.value[0];
- P[1] = (double)attr.value[1];
- P[2] = (double)attr.value[2];
+ /* Setup the surface position */
+ fragment->pos[0] = ray_org[0] + ray_dir[0] * hit->distance;
+ fragment->pos[1] = ray_org[1] + ray_dir[1] * hit->distance;
+ fragment->pos[2] = ray_org[2] + ray_dir[2] * hit->distance;
/* Normalize the geometry normal */
len = sqrt(f3_len(hit->normal));
- Ng[0] = (double)hit->normal[0] / len;
- Ng[1] = (double)hit->normal[1] / len;
- Ng[2] = (double)hit->normal[2] / len;
+ fragment->Ng[0] = hit->normal[0] / len;
+ fragment->Ng[1] = hit->normal[1] / len;
+ fragment->Ng[2] = hit->normal[2] / len;
/* Retrieve the tex coord */
S3D(primitive_has_attrib(&hit->prim, SSOL_TO_S3D_TEXCOORD, &has_texcoord));
if(!has_texcoord) {
- uv[0] = (double)hit->uv[0];
- uv[1] = (double)hit->uv[1];
+ fragment->uv[0] = hit->uv[0];
+ fragment->uv[1] = hit->uv[1];
} else {
S3D(primitive_get_attrib(&hit->prim, SSOL_TO_S3D_TEXCOORD, hit->uv, &attr));
ASSERT(attr.type == S3D_FLOAT2);
- uv[0] = (double)attr.value[0];
- uv[1] = (double)attr.value[1];
+ fragment->uv[0] = attr.value[0];
+ fragment->uv[1] = attr.value[1];
}
/* Retrieve and normalize the shading normal in world space */
S3D(primitive_has_attrib(&hit->prim, SSOL_TO_S3D_NORMAL, &has_normal));
if(!has_normal) {
- d3_set(Ns, Ng);
+ d3_set(fragment->Ns, fragment->Ng);
} else {
float transform[12];
float vec[3];
@@ -263,16 +253,28 @@ material_shade
}
len = sqrt(f3_len(attr.value));
- Ns[0] = (double)attr.value[0] / len;
- Ns[1] = (double)attr.value[1] / len;
- Ns[2] = (double)attr.value[2] / len;
+ fragment->Ns[0] = attr.value[0] / len;
+ fragment->Ns[1] = attr.value[1] / len;
+ fragment->Ns[2] = attr.value[2] / len;
}
+}
+
+res_T
+material_shade
+ (const struct ssol_material* mtl,
+ const struct surface_fragment* fragment,
+ const double wavelength, /* In nanometer */
+ struct brdf_composite* brdfs) /* Container of BRDFs */
+{
+ res_T res = RES_OK;
+ ASSERT(mtl);
/* Specific material shading */
switch(mtl->type) {
case MATERIAL_MIRROR:
- res = mirror_shade(mtl, wavelength, P, Ng, Ns, uv, w, brdfs);
+ res = mirror_shade(mtl, fragment, wavelength, brdfs);
break;
+ case MATERIAL_VIRTUAL: /* Nothing to shade */ break;
default: FATAL("Unreachable code\n"); break;
}
return res;
diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h
@@ -21,6 +21,14 @@
struct brdf_composite;
struct s3d_hit;
+struct surface_fragment {
+ double dir[3]; /* World space incoming direction */
+ double pos[3]; /* World space position */
+ double Ng[3]; /* Normalized world space primitive normal */
+ double Ns[3]; /* Normalized world space shading normal */
+ double uv[2]; /* Texture coordinates */
+};
+
enum material_type {
MATERIAL_VIRTUAL,
MATERIAL_MIRROR,
@@ -47,12 +55,18 @@ material_get_type(const struct ssol_material* mtl)
return mtl->type;
}
+extern LOCAL_SYM void
+surface_fragment_setup
+ (struct surface_fragment* fragment,
+ const float ray_org[3],
+ const float ray_dir[3],
+ const struct s3d_hit* hit);
+
extern LOCAL_SYM res_T
material_shade
(const struct ssol_material* mtl,
+ const struct surface_fragment* fragment,
const double wavelength, /* In nanometer */
- const struct s3d_hit* hit, /* Hit point to shade */
- const float w[3], /* Incoming direction */
struct brdf_composite* brdfs); /* Container of BRDFs */
#endif /* SSOL_MATERIAL_C_H */
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -259,6 +259,7 @@ hit_filter_function
struct ray_data* rdata;
struct ssol_object_instance* instance;
struct ssol_material* material;
+ const char* receiver_name;
(void)org, (void)dir, (void)filter_data;
ASSERT(rdata);
@@ -269,10 +270,27 @@ hit_filter_function
return 1; /* Discard self intersection */
instance = scene_get_object_instance_from_s3d_hit(rdata->scene, hit);
- material = object_get_material(object_instance_get_object(instance));
- if(material_get_type(material) == MATERIAL_VIRTUAL)
+ /* Check if the hit surface is a receiver that registers hit data */
+ receiver_name = object_instance_get_receiver_name(instance);
+ if(receiver_name) {
+ struct surface_fragment frag;
+ surface_fragment_setup(&frag, org, dir, hit);
+ fprintf(rdata->stream, "%s %u %u %g %g (%g:%g:%g) (%g:%g:%g) (%g:%g)\n",
+ receiver_name,
+ rdata->path_id,
+ rdata->ray_id,
+ rdata->wavelength,
+ rdata->radiance,
+ SPLIT3(frag.pos),
+ SPLIT3(frag.dir),
+ SPLIT2(frag.uv));
+ }
+
+ material = object_get_material(object_instance_get_object(instance));
+ if(material_get_type(material) == MATERIAL_VIRTUAL) {
return 1; /* Discard virtual material */
+ }
return 0;
}