Shader glossy_refraction_sample

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(&params->index_of_refraction); 
    miScalar shiny = *mi_eval_scalar(&params->shiny); 
    miUint samples = *mi_eval_integer(&params->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