Click on the filename to display or download the file.
specular_refraction.mi
declare shader
color "specular_refraction" (
scalar "index_of_refraction" default 1.33 )
version 1
apply material
end declare
specular_refraction.c
#include "shader.h"
#include "miaux.h"
struct specular_refraction {
miScalar index_of_refraction;
};
DLLEXPORT
int specular_refraction_version(void) { return 1; }
DLLEXPORT
miBoolean specular_refraction (
miColor *result, miState *state, struct specular_refraction *params )
{
miVector direction;
miScalar ior = *mi_eval_scalar(¶ms->index_of_refraction);
miaux_set_state_refraction_indices(state, ior);
if (mi_refraction_dir(&direction, state, state->ior_in, state->ior))
mi_trace_refraction(result, state, &direction);
else {
mi_reflection_dir(&direction, state);
if (!mi_trace_reflection(result, state, &direction))
mi_trace_environment(result, state, &direction);
}
return miTRUE;
}
specular_refraction_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;
}
22 April 2008 23:40:20