======================
Materials introduction
======================

Materials are a collection of settings that are used to decorate geometry. Materials are made of *components* that affect how the material is rendered. Examples of components are diffuse channel, emission, bump, gloss, and transmission. Every material has at least one component: the base color (which is known as its *diffuse* color). There are many ways to set the diffuse color, including :ref:`coloring the face directly <using_materials>`, :ref:`coloring vertices <prog_guide/0504_applying_materials:Example showing how to color vertices>`, using :doc:`color interpolation <0806_color_interpolation>`, or applying a :doc:`material <0501_materials_introduction>`.

Any object in a |HPSNOW| scene can receive a material, but some material components will be ignored by objects that cannot use them. For example, a shell can use almost every material component, but text can use only the face color. If, for example, you try to apply a bump setting to text, it will be ignored.


MaterialKit and MaterialMappingKit
----------------------------------

An important concept to understand is the difference between a ``HPS::MaterialKit`` and a ``HPS::MaterialMappingKit``. The ``HPS::MaterialKit`` represents one material and all the components therein such as color and texture. The ``HPS::MaterialMappingKit`` represents the *way* a material is applied to geometry. It is the mapping between the material itself and the geometry. So, for example, if you need to texture a piece of geometry with an image, you would build the material with the texture inside, then apply it to a shell's faces using a material mapping kit.

Creating a ``HPS::MaterialKit`` is relatively straightforward:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_materials_introduction.cpp
		   :start-after: //! [create_material_kit]
		   :end-before: //! [create_material_kit]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_materials_introduction.cs
		   :start-after: //! [create_material_kit]
		   :end-before: //! [create_material_kit]
		   
		   
.. _defining-material-palettes:

Defining Material Palettes
==========================

A particularly complex application might contain hundreds or even thousands of materials. Moreover, certain groups of materials might be common to one scene and not another. It can be difficult to organize the materials in a way that is easy to maintain. Because of this potential problem, |HPSNOW| offers a way to collect, organize, and apply materials when and where they are needed through the use of material palettes.

A ``HPS::MaterialPaletteDefinition`` is a collection of materials. Each defined material is indexed in a convenient way so that assigning and reassigning materials is similar to indexing an array. All ``HPS::MaterialPaletteDefinition`` objects live inside a :doc:`portfolio <0401_portfolios_introduction>`. Material palettes also allow you to apply transparent materials to subentities (individual faces, vertices, edges), something that is not possible otherwise.

The first step in building and using a palette is to create the materials that will exist within it. Here, we are using a ``HPS::MaterialKitArray`` instead of instantiating the materials independently:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_materials_introduction.cpp
		   :start-after: //! [material_kit_array]
		   :end-before: //! [material_kit_array]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_materials_introduction.cs
		   :start-after: //! [material_kit_array]
		   :end-before: //! [material_kit_array]

In the above snippet, three materials are created. The diffuse color component is set for all, and a gloss setting is applied to the second material. Other components can also be set this way in order to build a material that meets your specifications. After the materials are created, the palette is ready to be *defined*. This must be done through a ``HPS::PortfolioKey`` The palette must be given a name so that you can reference it later when assigning the palette to a segment. Any number of palettes can be defined in a portfolio.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_materials_introduction.cpp
		   :start-after: //! [material_palette_definition]
		   :end-before: //! [material_palette_definition]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_materials_introduction.cs
		   :start-after: //! [material_palette_definition]
		   :end-before: //! [material_palette_definition]
		   
		   
.. _using_materials:
		   
Using Materials
---------------

For convenience, many of the most common material settings can be applied to geometry without the use of a material palette. For example, if you want to quickly apply a color or make a gloss setting on a segment, you can use the ``HPS::MaterialMappingControl``:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_materials_introduction.cpp
		   :start-after: //! [using_material_mapping_control]
		   :end-before: //! [using_material_mapping_control]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_materials_introduction.cs
		   :start-after: //! [using_material_mapping_control]
		   :end-before: //! [using_material_mapping_control]
		   
While convenient for making small adjustments, the method shown in the code above would quickly become tedious if there were a large number of settings that needed to be applied to a large number of segments. This is where material palettes shine. All material palettes must be defined in a portfolio before they are able to be used. The snippet below shows how to set the material of all faces in a segment using a material palette:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_materials_introduction.cpp
		   :start-after: //! [using_material_palettes]
		   :end-before: //! [using_material_palettes]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_materials_introduction.cs
		   :start-after: //! [using_material_palettes]
		   :end-before: //! [using_material_palettes]


.. _override_internal_color:

Overriding Internal Color
-------------------------

Certain geometry, such as glyphs, lines, markers, and PBR materials may have an intrinsic color associated with them. The color is embedded at the geometry level and as such, setting color at the segment level will have no effect. For these cases, |HPSNOW| offers the ability to override this color. A ``HPS::VisibilityKit`` is used in conjunction with the ``HPS::DrawingAttributeControl`` to define which colors should be overriden. For example, to override the colors for markers and lines, you would do something like the following:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_materials_introduction.cpp
		   :start-after: //! [override_internal_color]
		   :end-before: //! [override_internal_color]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_materials_introduction.cs
		   :start-after: //! [override_internal_color]
		   :end-before: //! [override_internal_color]
