/* Uses same physically based scattering parameter as in transmission calculations, * along with artificial reflection scale/reflection color tint */ static void vol_get_reflection_color(ShadeInput *shi, float ref_col[3], const float co[3]) { float scatter = shi->mat->vol.scattering; float reflection = shi->mat->vol.reflection; copy_v3_v3(ref_col, shi->mat->vol.reflection_col); if (shi->mat->mapto_textured & (MAP_SCATTERING + MAP_REFLECTION_COL)) do_volume_tex(shi, co, MAP_SCATTERING + MAP_REFLECTION_COL, ref_col, &scatter, &R); /* only one single float parameter at a time... :s */ if (shi->mat->mapto_textured & (MAP_REFLECTION)) do_volume_tex(shi, co, MAP_REFLECTION, NULL, &reflection, &R); ref_col[0] = reflection * ref_col[0] * scatter; ref_col[1] = reflection * ref_col[1] * scatter; ref_col[2] = reflection * ref_col[2] * scatter; }
/* compute emission component, amount of radiance to add per segment * can be textured with 'emit' */ static void vol_get_emission(ShadeInput *shi, float emission_col[3], const float co[3]) { float emission = shi->mat->vol.emission; copy_v3_v3(emission_col, shi->mat->vol.emission_col); if (shi->mat->mapto_textured & (MAP_EMISSION + MAP_EMISSION_COL)) do_volume_tex(shi, co, MAP_EMISSION + MAP_EMISSION_COL, emission_col, &emission, &R); emission_col[0] = emission_col[0] * emission; emission_col[1] = emission_col[1] * emission; emission_col[2] = emission_col[2] * emission; }
/* compute emission component, amount of radiance to add per segment * can be textured with 'emit' */ static void vol_get_emission(ShadeInput *shi, float *emission_col, float *co) { float emission = shi->mat->vol.emission; VECCOPY(emission_col, shi->mat->vol.emission_col); if (shi->mat->mapto_textured & (MAP_EMISSION+MAP_EMISSION_COL)) do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission); emission_col[0] = emission_col[0] * emission; emission_col[1] = emission_col[1] * emission; emission_col[2] = emission_col[2] * emission; }
/* A combination of scattering and absorption -> known as sigma T. * This can possibly use a specific scattering color, * and absorption multiplier factor too, but these parameters are left out for simplicity. * It's easy enough to get a good wide range of results with just these two parameters. */ static void vol_get_sigma_t(ShadeInput *shi, float sigma_t[3], const float co[3]) { /* technically absorption, but named transmission color * since it describes the effect of the coloring *after* absorption */ float transmission_col[3] = {shi->mat->vol.transmission_col[0], shi->mat->vol.transmission_col[1], shi->mat->vol.transmission_col[2]}; float scattering = shi->mat->vol.scattering; if (shi->mat->mapto_textured & (MAP_SCATTERING + MAP_TRANSMISSION_COL)) do_volume_tex(shi, co, MAP_SCATTERING + MAP_TRANSMISSION_COL, transmission_col, &scattering, &R); sigma_t[0] = (1.0f - transmission_col[0]) + scattering; sigma_t[1] = (1.0f - transmission_col[1]) + scattering; sigma_t[2] = (1.0f - transmission_col[2]) + scattering; }
float vol_get_density(struct ShadeInput *shi, const float co[3]) { float density = shi->mat->vol.density; float density_scale = shi->mat->vol.density_scale; if (shi->mat->mapto_textured & MAP_DENSITY) do_volume_tex(shi, co, MAP_DENSITY, NULL, &density, &R); /* if meta-object, modulate by metadensity without increasing it */ if (shi->obi->obr->ob->type == OB_MBALL) { const float md = metadensity(shi->obi->obr->ob, co); if (md < 1.f) density *= md; } return density * density_scale; }