Decals are a first-class scene database element that allows you to place decals, such as stickers and labels, on objects in the scene, give them full MDL materials on their own, place them in space and selectively enable or disable them. The placement of decals on objects is physically based insofar as they can be placed on either side of a surface, they can overlap each other, and you can see through transparent decals and see other decals below it.
Decal scene element
The decal scene element is represented through the mi::neuraylib::IDecal interface. The implicit geometry of a decal is a unit square centered at the origin in the x-y-plane facing positive z-direction.
A decal scene element has the following fields and attributes:
- A clipping box that restricts the effects of the decal. The clipping box is an axis-aligned box defined in the object space of the decal. Note that the clipping box is different from a bounding box here in that it is part of the modeling capability with decals and not a conservative enclosure.
- A projector that defines how the decal is applied to the object.
Technically, a projector returns for the current surface position the
uv-coordinates that have to be used for the material on the decal.
A projector is thus a MDL function in Iray. The supported MDL function is base::coordinate_projection() with its coordinate_system parameter left at its default value of texture_coordinate_object. Without a projector function, the decal will use the uv-coordinates of the object itself, which is the default. This makes the decal behave more like texturing but with a full material layered on top of the objects material.
With or without projector, in both cases a base::transform_coordinate() function can be used in addition to transform the resulting uv-coordinates and thus position the decal in texture space.
- A texture space index to be used by the projector to temporarily store the uv-coordinates for the decal material evaluation. The default texture space is 0.
- A signed integer priority value which is used to resolve the ordering in case of overlapping decals. The default is 0 and negative values are allowed. A decal with higher priority is placed on top of a decal with lower priority.
- A material attribute (not a field). This attribute is the same as for
any other object, except that decals support only a single material and
not arrays of materials.
Materials on decals have a few restrictions:
- Materials are always thin-walled on decals.
- Front and back-side can have different surface properties. For example a label on a glass bottle can have the logo printed on the front-side while the back-side has a plain white paper surface.
- Decals support cutout opacity and transmissive materials.
- Emission is not supported.
- Normal maps are supported.
- Displacements are not supported.
- Volume properties are not supported, except that the IOR value is used in valid thin-walled surface material effects, like in the Fresnel-driven selection between reflection and transmission in the combined specular BSDF.
- An enum of type mi::neuraylib::Decal_face_mode that controls whether the decal appears on the front face (the default), the back face, or both faces of the objects surface. The face orientation is determined w.r.t. the projection direction. The normal derived from the orientation of the geometric primitives is not relevant. For non-thin-walled materials the decal is never shown on the face with higher density.
Placement of decals in space
Decals are placed in space similar to geometry objects with instance transformations using the mi::neuraylib::IInstance nodes.
However, unlike geometry objects, decals are not independent scene objects and they (or instances of them) are not connected in the scene graph using groups. Instead, decals or instances of decals are attached to the scene graph with the decals attribute, for example, on the geometry nodes themselves, on instance nodes or on group nodes.
The transformation between world space of the scene graph root group and the local object space of the decal consist of the concatenation of the individual instance transformations from the root group down to the node with the decals attribute and from there to the decal.
Decals can be instanced multiple times much like geometry objects, for example by using a decal in several instances, or attaching it to a node that is instanced multiple times. In addition, a decal or instances of a decal can be attached multiple times at different nodes, or even at the same node, for example, with different instance transformations.
This mechanism of placing decals in the scene and positioning them can be used to achieve different dynamic behaviors on scene updates. For example, given a car modeled with a car body and a movable door, a single decal can be used to place a sticker across the door and car body. When the door opens, the following two interesting scenarios can be modeled as detailed below:
- The conventional behavior of decals would leave the decal stationary, i.e., the decal keeps projecting, now distorted, onto the door.
- The part of the decal projecting onto the door rotates with the door and behaves like a sticker glued to the car.
The following two figures illustrate the scene graphs that model these two scenarios. In both, the transformation T2 is used to rotate the door.
Layering and placement of decals on objects
Decals can overlap each other and they can be visible on the front side or the back side of a surface.
When overlapping, decals create physical layers that determine the visibility of the decals. Transparency and cutout-opacity is also supported in that a transparent material of a decal allows you to see the decals below.
The order of overlapping decals is determined by their priority. A decal with a priority greater than another decal is above the other decal. If they are of equal priority, the decal that comes first in the sequence of decals in the decals attribute is above the other decal.
You can use the enum field value of type mi::neuraylib::Decal_face_mode to control on which side of a surface the decal is visible, the front side, the back side, or both sides. The front side of a surface for the purpose of decal visibility is the side whose angle between the implied face normal and the projector direction is larger than 90 degrees. The other side is the back side. If there is no projector then the front side is defined by the orientation of the surface primitives.
In addition, for surfaces with a non thin-walled base material a decal is never shown on the side with the higher density, i.e., the side with the higher IOR value. This is for example relevant when you model a label on a glass bottle using a cylindrical projector and you want to see the label only on the outside of the bottle and not on the inside of the glass towards the bottle interior. However, you can place a label on the inside of the bottle, with the mi::neuraylib::DECAL_ON_BACK_FACE value for the mi::neuraylib::Decal_face_mode enum value.
Selectively enabling and disabling decals in the scene graph
By default, all decals attached with the decals attribute are visible on all objects below the node where the attribute is attached.
The additional attributes, enabled_decals and disabled_decals, give you more fine-grained control over which decals are visible on which object. To understand their behavior, attribute inheritance needs to be understood for these attributes.
The inheritance of the enabled_decals and disabled_decals behaves like all other attributes. If they are not set explicitly, enabled_decals will be set to the value in decals by default, and disabled_decals will be empty by default, effectively making all decals visible under the rules explained below.
The inheritance of the decals attribute is special: the array elements of the child are always prepended to the array elements of the parent. Note that inheritance does not change the behavior of transformations explained above.
All three attributes are inherited down the scene graph and end in a geometry leaf node. A decal is now visible on a geometry leaf node if and only if it is listed in the decals attribute and in the enabled_decals attribute but not in the disabled_decals attribute.
The interplay of these rules can lead too fairly complicated constellations. We thus recommend to look first at a simple policy and see if it suffices to realize the desired modeling and workflow needs. The following example can serve as one.
One policy could be to attach decals at the root group -- they will not move with the geometry then -- and select their visibility explicitly at the instance nodes referencing the geometry. The example scene graph shown in Figure 3 illustrates this by modeling the tires of a car with four instances of the same tire geometry. The two decals in the scene graph are attached to the root group and each instance defines the enabled_decals attribute to define all the decals that are visible for this tire. In this example, decal D1 is visible on all tires and decal D2 only on the fourth tire.
The placement of all decals in the root group implied that they will not move with the geometry. For the decal D1 that is visible on all four tires, this also means that it is not positioned by the instance transformtions to be at the same place on all four tires. To model that, the decal would need to be attached to the four instance nodes.