Shader glossy_refraction_sample_varying

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