/*
 This Source Code Form is subject to the terms of the Mozilla Public
 License, v. 2.0. If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/


/*!
  \page vitelotte_user_manual_diffusion_images_page Diffusion curve images

  \section vitelotte_user_manual_diffusion_images_sec Diffusion curve images

  Diffusion curve images are images produced by diffusing colors defined on curves and points across some domain. It offers a simple way to create and edit smooth-shaded images exhibiting complex colors gradients.

  Diffusing colors from some constraints is the same as finding a function that interpolates these constraints. There are obviously several ways to do this. We will discuss two of them here: harmonic and biharmonic interpolation.

  To summarize, harmonic interpolation is relatively fast and easy to compute compared to biharmonic; however it has some limitations which makes it much harder to use for drawing. The biggest problem of harmonic interpolation is the fact that constrained curves are necessarily gradient-discontinuous and thus quite much visible. Biharmonic diffusion does not have this limitation and permits more natural color gradients, particularly when the goal is to reproduce shading:

  \image html vitelotte/diffusion_cmp.svg "With harmonic interpolation (left), shading curves are easily noticeable, whereas they are hardly visible with biharmonic interpolation (right). Creating the image on the right with harmonic diffusion would be very hard."

  For the same reason, point constraints are hardly usable with harmonic diffusion because they produce sharp color points instead of a smooth color gradients.

  However, biharmonic diffusion has one drawback: it extrapolates colors. It means that color values might go over the maximum displayable value (which may not be a problem if you do tone mapping) or below 0 (which is a more serious issue). Depending on the color space in which interpolation is done, this may lead to various artifacts, including color shifts.

  Fortunately, biharmonic diffusion also permits to easily control derivatives orthogonal to the curves. While the derivative of a color is not a very intuitive concept, it can be used to limit extrapolation. In practice, curves in the examples provided with Vitelotte either have no derivative constraints or we constrain them to be null.


  \section vitelotte_user_manual_diffusion_color_spaces_sec Color spaces

  Interpolating colors can be done in various color spaces, with different results. The relevant color space may depend on the application. Here is a quick comparison of different color spaces.

  <b>SRGB:</b> SRGB is the standard color space for common screens. As such, working directly in SRGB has the advantage that it does not require any color conversion for display. Moreover, varying colors intensity linearly in SRGB produces a nearly perceptually-linear color gradient. The main drawback is that intermediate colors when interpolating between two bright and saturated colors tend to be too dark.

  <b>Linear RGB or XYZ:</b> Working in a linear color space may be necessary sometimes. For instance, applying shading on a surface should be done in a linear color space to get good results. It is however not really adapted to the creation of color gradients because of the strong non-linearity of human perception.

  <b>Cie Lab / Cie Luv:</b> These color spaces have been designed specifically to be close to human perception. Computing the distance between two colors in these spaces should give a good approximation of how different the colors are for a human. They produce good results to compute diffusion curve images while avoiding the artifacts of SRGB. Although conversions to/from these color spaces are more expensive, they are the recommended color spaces to work with diffusion images. Luv seems to be a bit better than Lab for color gradients, but the difference is minimal.

  Keep in mind that to avoid artifacts with Vitelotte, you should compute diffusion and interpolate colors over each face using the same color space. Failing to do so may make the edge more easily noticeable. VGMeshRenderer does this properly and support all the above color spaces.

 */
