Click on the filename to display or download the file.
glossy_refraction_sample.mi
declare shader
color "glossy_refraction_sample" (
scalar "index_of_refraction" default 1.33,
scalar "shiny" default 50,
integer "samples" default 8 )
version 1
apply material
end declare
glossy_refraction_sample.c
#include "shader.h"
#include "miaux.h"
struct glossy_refraction_sample {
miScalar index_of_refraction;
miScalar shiny;
miInteger samples;
};
DLLEXPORT
int glossy_refraction_sample_version(void) { return 1; }
DLLEXPORT
miBoolean glossy_refraction_sample (
miColor *result, miState *state, struct glossy_refraction_sample *params )
{
miScalar ior = *mi_eval_scalar(¶ms->index_of_refraction);
miScalar shiny = *mi_eval_scalar(¶ms->shiny);
miUint samples = *mi_eval_integer(¶ms->samples);
miVector refract_dir, reflect_dir;
miColor refract_color;
int sample_number = 0;
double sample[2];
miaux_set_state_refraction_indices(state, ior);
result->r = result->g = result->b = 0.0;
while (mi_sample(sample, &sample_number, state, 2, &samples)) {
if (mi_transmission_dir_glossy_x(&refract_dir, state,
state->ior_in, state->ior,
shiny, sample)) {
if (mi_trace_refraction(&refract_color, state, &refract_dir))
miaux_add_color(result, &refract_color);
}
else {
mi_reflection_dir(&reflect_dir, state);
if (!mi_trace_reflection(&refract_color, state, &reflect_dir))
mi_trace_environment(&refract_color, state, &reflect_dir);
miaux_add_color(result, &refract_color);
}
}
miaux_scale_color(result, 1.0 / samples);
return miTRUE;
}
glossy_refraction_sample_util.c
void miaux_set_state_refraction_indices(miState *state,
miScalar material_ior)
{
miState *previous_transmission = NULL;
miScalar incoming_ior, outgoing_ior;
if (miaux_ray_is_entering(state, previous_transmission)) {
outgoing_ior = material_ior;
incoming_ior = miaux_state_outgoing_ior(state->parent);
} else {
incoming_ior = material_ior;
outgoing_ior = miaux_state_incoming_ior(previous_transmission);
}
state->ior_in = incoming_ior;
state->ior = outgoing_ior;
}
miBoolean miaux_ray_is_entering_material(miState *state)
{
miState *s;
miBoolean entering = miTRUE;
for (s = state; s != NULL; s = s->parent)
if (s->material == state->material)
entering = !entering;
return entering;
}
miBoolean miaux_ray_is_transmissive(miState *state)
{
return state->type == miRAY_TRANSPARENT ||
state->type == miRAY_REFRACT;
}
miBoolean miaux_parent_exists(miState *state)
{
return state->parent != NULL;
}
miBoolean miaux_shaders_equal(miState *s1, miState *s2)
{
return s1->shader == s2->shader;
}
miScalar miaux_state_outgoing_ior(miState *state)
{
miScalar unassigned_ior = 0.0, default_ior = 1.0;
if (state != NULL && state->ior != unassigned_ior)
return state->ior;
else
return default_ior;
}
miScalar miaux_state_incoming_ior(miState *state)
{
miScalar unassigned_ior = 0.0, default_ior = 1.0;
if (state != NULL && state->ior_in != unassigned_ior)
return state->ior_in;
else
return default_ior;
}
void miaux_add_color(miColor *result, miColor *c)
{
result->r += c->r;
result->g += c->g;
result->b += c->b;
result->a += c->a;
}
void miaux_scale_color(miColor *result, miScalar scale)
{
result->r *= scale;
result->g *= scale;
result->b *= scale;
}
22 April 2008 23:40:22