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 coloring the face directly, coloring vertices, using color interpolation, or applying a material.

Any object in a Visualize 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:

        HPS::MaterialKit materialKit;
        materialKit.SetDiffuse(HPS::RGBAColor(0.5f, 0.7f, 0.3f, 0.2f));
        materialKit.SetDiffuseTexture("myDefinedTexture");
        materialKit.SetSpecular(HPS::RGBAColor(1, 0.8f, 0.9f, 0.5f));
        materialKit.SetGloss(15.0f);

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, Visualize 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 portfolio. 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:

        HPS::MaterialKitArray materialKitArray(3);
        materialKitArray[0].SetDiffuse(HPS::RGBAColor(1, 0, 0, 1)); // opaque
        materialKitArray[1].SetDiffuse(HPS::RGBAColor(1, 0, 0, 0.5f)); // half transparent
        materialKitArray[1].SetGloss(0.5f);
        materialKitArray[2].SetDiffuse(HPS::RGBAColor(1, 0, 0, 0)); // fully transparent

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.

        HPS::MaterialPaletteDefinition mpd = myPortfolio.DefineMaterialPalette("myPalette", materialKitArray);
        mySegmentKey.SetMaterialPalette("myPalette"); // the palette is made active on the segment

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:

        // setting a color on a single segment
        mySegmentKey.GetMaterialMappingControl().SetFaceColor(HPS::RGBAColor(1.0f, 0, 0, 0.5f));

        // setting gloss on a single segment
        mySegmentKey.GetMaterialMappingControl().SetFaceGloss(12.4f);

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:

        HPS::PortfolioKey myPortfolio = HPS::Database::CreatePortfolio();

        // defining a material palette with the name of "myPalette"
        // and the materials within "materialKitArray"
        myPortfolio.DefineMaterialPalette("myPalette", materialKitArray);

        // setting the portfolio active on the segment
        mySegmentKey.GetPortfolioControl().Set(myPortfolio);

        // using material '0' from "materialKitArray"
        mySegmentKey.GetMaterialMappingControl().SetFaceMaterialByIndex(0);

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, Visualize 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:

        HPS::VisibilityKit visibilityKit;
        visibilityKit.SetEverything(false).SetMarkers(true).SetLines(true);
        mySegmentKey.GetDrawingAttributeControl().SetOverrideInternalColor(visibilityKit);