#include "shader.h" #include "miaux.h" struct hair_color_light { miColor ambient; miColor diffuse; miColor specular; miScalar exponent; miScalar root_opacity; miScalar tip_opacity; miScalar color_variance; int i_light; int n_light; miTag light[1]; }; DLLEXPORT int hair_color_light_version(void) { return 1; } void hair_color_variance( miColor *result, miState *state, struct hair_color_light* params) { miScalar maximum_variance = *mi_eval_scalar(¶ms->color_variance); miScalar color_variance = miaux_fit(state->tex_list[0].x, 0.0, 1.0, 1.0 - maximum_variance, 1.0 + maximum_variance); *result = *mi_eval_color(¶ms->diffuse); miaux_scale_color(result, color_variance); miaux_clamp_color(result); } miScalar hair_alpha(miState *state, struct hair_color_light* params) { return miaux_fit(state->bary[1], 0.0, 1.0, *mi_eval_scalar(¶ms->root_opacity), *mi_eval_scalar(¶ms->tip_opacity)); } miBoolean hair_shadow(miColor *result, miColor *diffuse, miScalar alpha) { miScalar threshold = 0.001; miScalar transparency = 1.0 - alpha; result->r *= miaux_shadow_breakpoint(diffuse->r, transparency, 0.2); result->g *= miaux_shadow_breakpoint(diffuse->g, transparency, 0.2); result->b *= miaux_shadow_breakpoint(diffuse->b, transparency, 0.2); if (result->r < threshold && result->g < threshold && result->b < threshold) return miFALSE; else return miTRUE; } DLLEXPORT miBoolean hair_color_light ( miColor *result, miState *state, struct hair_color_light *params ) { int i, light_count, light_sample_count; miColor diffuse, sum, light_color, *specular; miVector direction_toward_light, to_camera; miScalar dot_nl, alpha; miTag *light; miVector hair_tangent = state->derivs[0]; miVector original_normal = state->normal; hair_color_variance(&diffuse, state, params); alpha = hair_alpha(state, params); if (state->type == miRAY_SHADOW) return hair_shadow(result, &diffuse, alpha); state->normal.x = state->normal.y = state->normal.z = 0.0f; to_camera = state->dir; mi_vector_neg(&to_camera); mi_vector_normalize(&hair_tangent); specular = mi_eval_color(¶ms->specular); *result = *mi_eval_color(¶ms->ambient); result->a = alpha; miaux_light_array(&light, &light_count, state, ¶ms->i_light, ¶ms->n_light, params->light); for (i = 0; i < light_count; i++, light++) { miaux_set_channels(&sum, 0); light_sample_count = 0; while (mi_sample_light(&light_color, &direction_toward_light, &dot_nl, state, *light, &light_sample_count)) { miaux_add_diffuse_hair_component( &sum, &hair_tangent, &direction_toward_light, &diffuse, &light_color); miaux_add_specular_hair_component( &sum, &hair_tangent, &direction_toward_light, &to_camera, specular, &light_color); } if (light_sample_count) miaux_add_scaled_color(result, &sum, 1.0/light_sample_count); } state->normal = original_normal; if (result->a < 0.999) miaux_add_transparent_hair_component(result, state); return miTRUE; }