Creating Classic Materials
Materials define the way the surfaces of your meshes react to light.
You define materials within a scene. When you create a mesh, you give each of its
triangles a material by name. Then, when you create an instance of a mesh within a
scene, each of its triangles uses the material in that scene whose name matches the
name of the material assigned to it when the mesh was created. See Creating Meshes. You can also override the materials used in each instance of a mesh. See Creating Mesh Instances.
NOTE:The "classic materials" approach described on this page is now considered deprecated,
although it is still supported in the current release. If you are starting a new integration
of
Beast, it is highly recommended that you use the new physical material system, as described
in
Creating Physical Materials. If you do intend to use the material system outlined below, you must create your
scene using the
ILBBeginScene() function instead of
ILBBeginPhysicalScene().
Channels
In Beast, materials are based on the Phong model. They contain multiple channels, identified
by the elements in the ILBMaterialChannel enumeration. Each channel defines a different kind of information about the material,
and can store different kinds of data.
Color channels
The following channels store a color value and a scalar value that determines the
scale or intensity of that color.
- The diffuse channel (ILB_CC_DIFFUSE) stores the base color of the surface.
- The specular channel (ILB_CC_SPECULAR) stores the color used for specular highlights.
- The emissive channel (ILB_CC_EMISSIVE) stores a color that should be emitted from the surface.
- The transparency channel (ILB_CC_TRANSPARENCY) determines what color of incoming light will shine through the surface. It is defined
in the opposite way to a typical alpha channel, so that if you set the color value
to (1.0f, 0.0f, 0.0f) the object will let red light pass through. Its shadow will also appear to be red.
- The non-directional channel (ILB_CC_NONDIRECTIONAL) allows you to blend in a lighting contribution that is independent of the surface
normal. This is useful for objects like vegetation that have very simple geometry
representations. The nondirectional contribution is only added to the baked results,
but never affects the light simulation. You can scale the intensity of the nondirectional
contribution by calling ILBSetNondirectionalScale(). This channel is only supported for the RNM render pass. See also Creating Render Passes.
- The normal map channel (ILB_CC_NORMAL) allows you to provide a high-detail representation of local deviations in the surface
texture. These normal maps are taken into account during the illumination pass.
The color in each of these channels may be drawn from any of the following sources:
- It may be a flat constant value. You can set the color value of a channel through
a call to ILBSetMaterialColor().
- It may be drawn from a texture. You can set the texture of a channel through a call
to ILBSetMaterialTexture().
- It may be drawn from vertex colors stored in the mesh. The vertex colors are interpolated
across the face of each triangle. You can enable vertex coloring for a channel through
a call to ILBSetMaterialUseVertexColors().
Scalar values for these channels are set to 1 by default. You can change the scalar
value through a call to ILBSetMaterialScale().
Scalar-only channels
The following channels store only a scalar value:
- The shininess channel (ILB_CC_SHININESS) determines how smooth and glossy the surface appears. Materials with high values
will have small, sharp specular highlights; materials with low values will have wider,
less intense specular highlights.
- The reflectivity channel (ILB_CC_REFLECTION) determines how much of the incoming light is reflected back from the surface. Reflection
strength is computed by multiplying the specular channel with the reflection channel.
This means that the value you set for the specular channel affects reflections as
well.
Scalar values for these channels are set to 1 by default. You can change the scalar
value through a call to ILBSetMaterialScale().
About transparency
You can make your materials transparent in either of the following ways:
- By setting color values in the transparency channel.
- By using the alpha values set in the diffuse channel to determine how opaque the material
is. To set this up, call the ILBSetAlphaAsTransparency() function. Alpha values of 1 will be opaque; alpha values of 0 will be transparent.
Note that this approach produces monochrome shadows.
Note that in either case, the transparency does not affect specular highlights, emissive
light or reflections.
The formula
For each light, the following equation is computed:
(N * L) D (1 - T) + S(R * V )s
Reflections, transmission and emissive colors are added as follows:
Where:
- N is the normal of the surface.
- L is the direction towards the light source.
- D is the diffuse color of the fragment multiplied by its scale.
- T is the transparency of the fragment multiplied by its scale.
- E is the emissive color of the fragment multiplied by its scale.
- R is the reflected light direction.
- V is the direction towards the viewer.
- S is the specular color of the fragment multiplied by its scale.
- s is the shininess of the fragment.
- CT is the color of the transmitted ray.
- r is the reflectivity of the fragment.
- CR is the color of the reflection ray.
Insubstantial materials
When working with global illumination, insubstantial materials that amplify light
can be problematic since they can drench the scene in light. To avoid this, make the
object glow or emit light using the emissive channel rather than large diffuse or
specular values.
Clamping the material colors can also be a good idea. There is an option to do this
automatically in the XML configuration file; see the <clampMaterials> setting under GISettings.
Setting up a classic material
You can only set up a material in the context of setting up a scene. See also Creating a Scene.
To set up a material:
- Create a new ILBMaterialHandle.
- Initialize the handle by calling ILBCreateMaterial(). In your call, you have to specify the handle of the scene that will contain your
material, and the name of the material. This name should match the name of the material
assigned to the triangles in your mesh.
- Set up the channels for the material with the desired colors and strengths. For details,
see Creating Classic Materials above.
You do not have to close or finalize the material in order to use it in a rendering
pass.
For example, the following code sets up a shiny material whose base diffuse channel
comes from a texture, and whose specular channel reflects bluish highlights:
ILBMaterialHandle myMat;
ILBCreateMaterial(scene, _T("TexturedSpec"), &sm1);
ILBSetMaterialTexture(sm1, ILB_CC_DIFFUSE, tex);
ILBSetMaterialColor(sm1, ILB_CC_SPECULAR, ILBLinearRGBA(0.23f, 0.10f, .7f, 1.0f));
ILBSetMaterialScale(sm1, ILB_CC_SHININESS, 20.0f);
Thread safety
You can create multiple different materials simultaneously in multiple threads. In
addition, multiple threads can find materials in the cache and use them simultaneously.
You can also modify a single material from multiple different threads at the same
time.
Related API functions
API functions related to the creation and setup of materials are declared in the beastmaterial.h file.