Shader glossy_refraction_sample_varying
|
Scenes
Home
|
Click on the filename to display or download the file.
glossy_refraction_sample_varying.mi
declare shader
color "glossy_refraction_sample_varying" (
scalar "index_of_refraction" default 1.33,
scalar "shiny" default 50,
array integer "samples" )
version 1
apply material
end declare
glossy_refraction_sample_varying.c
#include "shader.h"
#include "miaux.h"
struct glossy_refraction_sample_varying {
miScalar index_of_refraction;
miScalar shiny;
int i_samples;
int n_samples;
int samples[1];
};
DLLEXPORT
int glossy_refraction_sample_varying_version(void) { return 1; }
DLLEXPORT
miBoolean glossy_refraction_sample_varying (
miColor *result, miState *state,
struct glossy_refraction_sample_varying *params )
{
miScalar ior = *mi_eval_scalar(¶ms->index_of_refraction);
miScalar shiny = *mi_eval_scalar(¶ms->shiny);
int i_samples = *mi_eval_integer(¶ms->i_samples);
int n_samples = *mi_eval_integer(¶ms->n_samples);
int *samples = mi_eval_integer(params->samples) + i_samples;
miVector refraction_dir, reflect_dir;
miColor refract_color, reflect_color;
int sample_number = 0;
double sample[2];
miUint sample_count;
sample_count = samples[state->refraction_level >= n_samples ?
n_samples - 1 :
state->refraction_level];
miaux_set_state_refraction_indices(state, ior);
if (sample_count == 1) {
if (mi_transmission_dir_glossy(&refraction_dir, state,
state->ior_in, state->ior, shiny))
mi_trace_refraction(result, state, &refraction_dir);
else {
mi_reflection_dir(&reflect_dir, state);
if (!mi_trace_reflection(result, state, &reflect_dir))
mi_trace_environment(result, state, &reflect_dir);
}
} else {
result->r = result->g = result->b = 0.0;
while (mi_sample(sample, &sample_number, state, 2, &sample_count)) {
if (mi_transmission_dir_glossy_x(&refraction_dir, state,
state->ior_in, state->ior,
shiny, sample)) {
if (mi_trace_refraction(&refract_color, state, &refraction_dir))
miaux_add_color(result, &refract_color);
}
else {
mi_reflection_dir(&reflect_dir, state);
if (!mi_trace_reflection(&reflect_color, state, &reflect_dir))
mi_trace_environment(&reflect_color, state, &reflect_dir);
miaux_add_color(result, &reflect_color);
}
}
miaux_scale_color(result, 1.0 / sample_count);
}
return miTRUE;
}
glossy_refraction_sample_varying_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:23