The following functions are provided for support of shaders, to simplify common mathematical operations required in shaders:

##### mi_fresnel
```miScalar mi_fresnel(
miScalar        ior_in,
miScalar        ior_out,
miScalar        factor1,
miScalar        factor2);
```

Compute the reflected intensity according to Fresnel, given the index of refraction ior_in in the current medium and the index of refraction ior_out in the medium on the other side, which the ray is about to enter. The factors define the medium opacities.

##### mi_fresnel_reflection
```miScalar mi_fresnel_reflection(
miState         *state,
miScalar        ior_in,
miScalar        ior_out);
```

Call mi_fresnel with parameters appropriate for the given indices of refraction ior_in and ior_out, and for the dot_nd state variable.

##### mi_phong_specular
```miScalar mi_phong_specular(
miScalar        spec_exp,
miState         *state,
miVector        *dir);
```

Calculate the Phong factor based on the direction of illumination dir, the specular exponent spec_exp, and the state variables normal and dir. The direction must be given in internal space.

##### mi_fresnel_specular
```void mi_fresnel_specular(
miScalar        *ns,
miScalar        *ks,
miScalar        spec_exp,
miState         *state,
miVector        *dir,
miScalar        ior_in,
miScalar        iot_out);
```

Calculate the specular factor ns based on the illumination direction dir, the specular exponent spec_exp, the inside and outside indices of refraction ior_in and ior_out, and the state variables normal and dir. ks is the value returned by mi_fresnel, which is called by mi_fresnel_specular. The direction must be given in internal space.

##### mi_cooktorr_specular
```miBoolean mi_cooktorr_specular(
miColor         *result,
miVector        *dir_in,
miVector        *dir_out,
miVector        *normal,
miScalar        roughness,
miColor         *ior);
```

Calculate the specular color result according to the Cook-Torrance reflection model for incident direction dir_in, reflection direction dir_out at a surface with normal normal. The roughness is the average slope of surface microfacets. ior is the relative index of refraction for three wavelengths (ior_out/ior_in for red, green, and blue). All indices must be 1.0 or greater; if not they are clamped to 1.0. See Foley90.

##### mi_blinn_specular
```miScalar mi_blinn_specular(
miVector        *dir_in,
miVector        *dir_out,
miVector        *normal,
miScalar        roughness,
miScalar        ior);
```

Like mi_cooktorr_specular, but only for one wavelength. Only one index of refraction ior is needed, and the result is a scalar. If ior is less than 1.0, it is clamped to 1.0. See Foley90.

##### mi_blong_specular
```miScalar mi_blong_specular(
miVector        *dir_in,
miVector        *dir_out,
miVector        *normal,
miScalar        roughness,
miScalar        ior);
```

This is similar to mi_blinn_specular, but implements a hybrid of Blinn and Phong shading instead of true Blinn shading. It is included separately to support the Softimage Blinn shading model.

##### mi_ward_glossy
```miScalar mi_ward_glossy(
miVector        *dir_in,
miVector        *dir_out,
miVector        *normal,
miScalar        shiny);
```

Calculate the value of the isotropic Ward glossy reflection model for incident direction dir_in, reflection direction dir_out at a surface with normal normal and shinyness shiny. dir_in should point towards the point, while dir_out and normal should point away from the point. Shiny should be low (for example 5) for wide glossy reflection, and high (for example 100) for narrow glossy (nearly specular) reflection.

##### mi_ward_anisglossy
```miScalar mi_ward_anisglossy(
miVector        *dir_in,
miVector        *dir_out,
miVector        *normal,
miVector        *u,
miVector        *v,
miScalar        shiny_u,
miScalar        shiny_v);
```

Calculate the value of the anisotropic Ward glossy reflection model for incident direction dir_in, reflection direction dir_out, surface normal normal, and the anisotropic orientation determined by two perpendicular vectors u and v. The shinyness in the u and v direction is shiny_u and shiny_v, respectively. dir_in should point towards the point, while dir_out and normal should point away from the point. u and v should be perpendicular, and also perpendicular to the normal.

##### mi_schlick_scattering
```miScalar mi_schlick_scatter(
miVector        *dir_in,
miVector        *dir_out,
miScalar        directionality);
```

Calculate the value of the Schlick volume scattering model for incident direction dir_in, scattering direction dir_out, and directionality directionality. dir_in should point towards the point, while dir_out should point away from the point. directionality must be between -1 and 1. For values between -1 and 0 it models backscattering (with -1 being the most directional), for a value of 0 it models diffuse (isotropic) scattering, and for values between 0 and 1 it models forward scattering.

##### mi_choose_scatter_type
```miRay_type mi_choose_scatter_type(
miState         *state,
float           transp,
miColor         *diffuse,
miColor         *glossy,
miColor         *specular)
```

In photon shaders it is generally important (although not required) to generate only one photon per photon interaction. To make this happen this function can be used to select one of several new photon types. The function returns: miPHOTON_REFLECT_SPECULAR, miPHOTON_REFLECT_GLOSSY, miPHOTON_REFLECT_DIFFUSE, miPHOTON_TRANSMIT_SPECULAR, miPHOTON_TRANSMIT_GLOSSY, miPHOTON_TRANSMIT_DIFFUSE or miPHOTON_ABSORBED. The return type is based on incoming coefficients and chosen in such a way that the most important component is chosen most often. Notice that for caustics simulations the diffuse and glossy components are ignored. Also note that the sum of the diffuse, glossy and specular coefficients should be less than or equal to one within each of the red, green, and blue color bands, and that mi_choose_scatter_type modifies the input coefficients and scales them correctly based on the probability of generating a photon of that type. To obtain a correct result the shader must use the modified coefficients in the computations performed after mi_choose_scatter_type has been used. The probability for reflection is 1-transp. See page scatterfunc for a more detailed explanation.

##### mi_choose_simple_scatter_type
```miRay_type mi_choose_simple_scatter_type(
miState         *state,
miColor         *refl_diffuse,
miColor         *refl_specular,
miColor         *trans_diffuse,
miColor         *trans_specular)
```

This is a simplified version of mi_choose_scatter_type that simply returns the diffuse and specular terms for reflected and transmitted light. Unlike mi_choose_scatter_type, it does not support glossy interactions.

##### mi_choose_lobe
```int mi_choose_lobe(
miState         *state,
miScalar        r);
```

In a two-lobed volume scattering model, choose lobe 1 or 2 based on the probability r of the first lobe.