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(¶ms->transparency);
if (state->type == miRAY_SHADOW) {
miColor *color = mi_eval_color(¶ms->color);
miScalar breakpoint = *mi_eval_scalar(¶ms->breakpoint);
miScalar center = *mi_eval_scalar(¶ms->center);
miScalar extent = *mi_eval_scalar(¶ms->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(¶ms->color);
else {
mi_trace_transparent(result, state);
if (!miaux_all_channels_equal(transparency, 1.0)) {
miColor *color = mi_eval_color(¶ms->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