Shader transparent_shadow

Click on the filename to display or download the file.

transparent_shadow.mi
declare shader 
    color "transparent_shadow" ( 
        color "color", 
        color "transparency", 
	scalar "breakpoint", 
	scalar "center", 
	scalar "extent" ) 
    version 1 
    apply material, shadow 
end declare 

transparent_shadow.c
#include "shader.h" 
#include "miaux.h" 
 
struct transparent_shadow {  
    miColor color;  
    miColor transparency; 
    miScalar breakpoint; 
    miScalar center; 
    miScalar extent; 
}; 
 
DLLEXPORT 
int transparent_shadow_version(void) { return(1); } 
 
DLLEXPORT 
miBoolean transparent_shadow ( 
    miColor *result, miState *state, struct transparent_shadow *params  ) 
{ 
    miColor *transparency = mi_eval_color(&params->transparency); 
 
    if (state->type == miRAY_SHADOW) { 
        miColor *color = mi_eval_color(&params->color); 
        miScalar breakpoint = *mi_eval_scalar(&params->breakpoint); 
        miScalar center = *mi_eval_scalar(&params->center); 
        miScalar extent = *mi_eval_scalar(&params->extent); 
 
        result->r *= miaux_shadow_breakpoint_scale(color->r, transparency->r,  
                                                   breakpoint, center, extent); 
        result->g *= miaux_shadow_breakpoint_scale(color->g, transparency->g, 
                                                   breakpoint, center, extent); 
        result->b *= miaux_shadow_breakpoint_scale(color->b, transparency->b, 
                                                   breakpoint, center, extent); 
        return miaux_all_channels_equal(result, 0.0) ? miFALSE : miTRUE; 
    } 
    if (miaux_all_channels_equal(transparency, 0.0)) 
        *result = *mi_eval_color(&params->color); 
    else { 
        mi_trace_transparent(result, state); 
        if (!miaux_all_channels_equal(transparency, 1.0)) { 
            miColor *color = mi_eval_color(&params->color); 
            miColor opacity; 
            miaux_invert_channels(&opacity, transparency); 
            mi_opacity_set(state, &opacity); 
            miaux_blend_channels(result, color, transparency); 
        } 
    } 
    return miTRUE; 
} 

transparent_shadow_util.c
double miaux_shadow_breakpoint_scale ( 
    double color, double transparency, double breakpoint,  
    double center, double extent ) 
{ 
    double scaled_color =  
	miaux_fit(color, 0, 1, center - extent/2.0, center + extent/2.0); 
    if (transparency < breakpoint) 
	return miaux_fit(transparency, 0, breakpoint, 0, scaled_color); 
    else 
	return miaux_fit(transparency, breakpoint, 1, scaled_color, 1); 
} 
 
double miaux_fit( 
    double v, double oldmin, double oldmax, double newmin, double newmax)     
{ 
    return newmin + ((v - oldmin) / (oldmax - oldmin)) * (newmax - newmin); 
} 
 
miBoolean miaux_all_channels_equal(miColor *c, miScalar v) 
{ 
    if (c->r == v && c->g == v && c->b == v && c->a == v) 
	return miTRUE; 
    else 
	return miFALSE; 
} 
 
void miaux_invert_channels(miColor *result, miColor *color) 
{ 
    result->r = 1.0 - color->r; 
    result->g = 1.0 - color->g; 
    result->b = 1.0 - color->b; 
    result->a = 1.0 - color->a; 
} 
 
void miaux_blend_channels(miColor *result, 
			  miColor *blend_color, miColor *blend_fraction) 
{ 
    result->r = miaux_blend(result->r, blend_color->r, blend_fraction->r); 
    result->g = miaux_blend(result->g, blend_color->g, blend_fraction->g); 
    result->b = miaux_blend(result->b, blend_color->b, blend_fraction->b); 
} 
 
double miaux_blend(miScalar a, miScalar b, miScalar factor) 
{ 
    return a * factor + b * (1.0 - factor); 
} 

22 April 2008 23:40:16