void do_diffuse_and_spec(miColor *result,miState *state,miColor *diffuse, miColor *specular,miScalar specular_exponent){ // Lights stuff miTag *light = (miTag *) malloc(sizeof(miTag *)); int light_sample_count = 0; int light_count = 0; miScalar dot_normal_light; miColor light_color; // TMP variables miColor sum; miVector light_direction; miScalar spec_amount; //resultValues miColor *diffuse_out = (miColor *) malloc(sizeof(miColor *)); miColor *specular_out = (miColor *) malloc(sizeof(miColor *)); mi_inclusive_lightlist(&light_count, &light, state); for (mi::shader::LightIterator iter(state, light, light_count); !iter.at_end(); ++iter) { light_sample_count = 0; sum.r = sum.g = sum.b = 0; while(iter->sample()){ dot_normal_light = iter->get_dot_nl(); iter->get_contribution(&light_color); light_direction = iter->get_direction(); miVector normal = state->normal; spec_amount = pow(mi_vector_dot(&normal,&light_direction),specular_exponent); diffuse_out->r = (dot_normal_light * diffuse->r * light_color.r); diffuse_out->g = (dot_normal_light * diffuse->g * light_color.g); diffuse_out->b = (dot_normal_light * diffuse->b * light_color.b); specular_out->r = (specular->r * light_color.r * spec_amount); specular_out->g = (specular->g * light_color.g * spec_amount); specular_out->b = (specular->b * light_color.b * spec_amount); sum.r += diffuse_out->r + specular_out->r; sum.g += diffuse_out->g + specular_out->g; sum.b += diffuse_out->b + specular_out->b; light_sample_count++; } if (light_sample_count){ result->r += sum.r*(1.0/light_sample_count); result->g += sum.g*(1.0/light_sample_count); result->b += sum.b*(1.0/light_sample_count); } } }
extern "C" DLLEXPORT miBoolean mib_illum_lambert( miColor *result, miState *state, struct mib_illum_lambert *paras) { miColor *ambi, *diff; miTag *light; /* tag of light instance */ int n_l; /* number of light sources */ int i_l; /* offset of light sources */ int m; /* light mode: 0=all, 1=incl, 2=excl */ int samples; /* # of samples taken */ miColor color; /* color from light source */ miColor sum; /* summed sample colors */ miScalar dot_nl; /* dot prod of normal and dir*/ /* check for illegal calls */ if (state->type == miRAY_SHADOW || state->type == miRAY_DISPLACE ) { return(miFALSE); } ambi = mi_eval_color(¶s->ambient); diff = mi_eval_color(¶s->diffuse); m = *mi_eval_integer(¶s->mode); *result = *mi_eval_color(¶s->ambience); /* ambient term */ result->r *= ambi->r; result->g *= ambi->g; result->b *= ambi->b; n_l = *mi_eval_integer(¶s->n_light); i_l = *mi_eval_integer(¶s->i_light); light = mi_eval_tag(paras->light) + i_l; if (m == 1) /* modify light list (inclusive mode) */ mi_inclusive_lightlist(&n_l, &light, state); else if (m == 2) /* modify light list (exclusive mode) */ mi_exclusive_lightlist(&n_l, &light, state); else if (m == 4) { n_l = 0; light = 0; } /* Loop over all light sources */ if (m==4 || n_l) { for (mi::shader::LightIterator iter(state, light, n_l); !iter.at_end(); ++iter) { sum.r = sum.g = sum.b = 0; while (iter->sample()) { dot_nl = iter->get_dot_nl(); iter->get_contribution(&color); sum.r += dot_nl * diff->r * color.r; sum.g += dot_nl * diff->g * color.g; sum.b += dot_nl * diff->b * color.b; } samples = iter->get_number_of_samples(); if (samples) { result->r += sum.r / samples; result->g += sum.g / samples; result->b += sum.b / samples; } } } /* add contribution from indirect illumination (caustics) */ mi_compute_irradiance(&color, state); result->r += color.r * diff->r; result->g += color.g * diff->g; result->b += color.b * diff->b; result->a = 1; return(miTRUE); }
extern "C" DLLEXPORT miBoolean mib_illum_cooktorr( miColor *result, miState *state, struct mib_illum_cooktorr *paras) { miColor *ambi, *diff, *spec; miScalar roughness; /* average microfacet slope */ miColor *ior; /* index of refraction */ miTag *light; /* tag of light instance */ int n_l; /* number of light sources */ int i_l; /* offset of light sources */ int mode; /* light mode: 0=all, 1=incl, 2=excl */ int samples; /* # of samples taken */ miColor color; /* color from light source */ miColor sum; /* summed sample colors */ miVector dir; /* direction towards light */ miScalar dot_nl; /* dot prod of normal and dir */ miColor refl; /* specular reflection color */ /* check for illegal calls */ if (state->type == miRAY_SHADOW || state->type == miRAY_DISPLACE ) { return(miFALSE); } ambi = mi_eval_color(¶s->ambient); diff = mi_eval_color(¶s->diffuse); spec = mi_eval_color(¶s->specular); roughness = *mi_eval_scalar(¶s->roughness); ior = mi_eval_color(¶s->ior); *result = *mi_eval_color(¶s->ambience); /* ambient term */ result->r *= ambi->r; result->g *= ambi->g; result->b *= ambi->b; mode = *mi_eval_integer(¶s->mode); n_l = *mi_eval_integer(¶s->n_light); i_l = *mi_eval_integer(¶s->i_light); light = mi_eval_tag(paras->light) + i_l; if (mode == 1) /* modify light list (inclusive mode) */ mi_inclusive_lightlist(&n_l, &light, state); else if (mode == 2) /* modify light list (exclusive mode) */ mi_exclusive_lightlist(&n_l, &light, state); else if (mode == 4) { n_l = 0; light = 0; } /* Loop over all light sources */ if (mode == 4 || n_l) { for (mi::shader::LightIterator iter(state, light, n_l); !iter.at_end(); ++iter) { sum.r = sum.g = sum.b = 0; samples = 0; while (iter->sample()) { iter->get_contribution(&color); dot_nl = iter->get_dot_nl(); /* Diffuse reflection: Lambert's cosine law */ sum.r += dot_nl * diff->r * color.r; sum.g += dot_nl * diff->g * color.g; sum.b += dot_nl * diff->b * color.b; /* Specular reflection: Cook-Torrance reflection */ dir = iter->get_direction(); if (mi_cooktorr_specular(&refl, &state->dir, &dir, &state->normal, roughness, ior)) { sum.r += refl.r * spec->r * color.r; sum.g += refl.g * spec->g * color.g; sum.b += refl.b * spec->b * color.b; } } samples = iter->get_number_of_samples(); if (samples) { result->r += sum.r / samples; result->g += sum.g / samples; result->b += sum.b / samples; } } } /* add contribution from indirect illumination (caustics) */ mi_compute_irradiance(&color, state); result->r += color.r * diff->r; result->g += color.g * diff->g; result->b += color.b * diff->b; result->a = 1; return(miTRUE); }