2.7. The Material Node

The material node is used to define surface properties of an object. It does this by defining a set of primitives, known as fragments. Fragments are operators that process triplets of values, very suitable for representing color but also re-usable for other properties of a surface. For colors, the standard interpretation of a value is that 0 is black and 1 is white, but values can be outside this range (at both ends) without being clipped or considered invalid.

To define e.g. color (the typical use for a material node), begin by creating an output fragment, setting its type to "color", and then create any further fragments as desired, linking them to the root and each other to form the final material tree. The tree is then evaluated for every point of each surface that uses that material, and the result used to control the final shading.

2.7.1. Fragments

Table 2-2 enumerates the defined fragment types, and also gives the numerical value associated with each one. This number is used to identify a fragment type in the network protocol.

Table 2-2. Material Node Fragment Type Enumeration

NameEnum ValuePurpose
VN_M_FT_COLOR0Emits a constant color.
VN_M_FT_LIGHT1Represents light falling on a surface.
VN_M_FT_REFLECTION2Represents reflected light.
VN_M_FT_TRANSPARENCY3Represents a transparent surface.
VN_M_FT_VOLUME4Represents a volume diffusion.
VN_M_FT_VIEW5Represents the vector between camera and surface.
VN_M_FT_GEOMETRY6Uses data from a geometry layer to create color.
VN_M_FT_TEXTURE7Does look-ups in a bitmap node.
VN_M_FT_NOISE8Generates random noise.
VN_M_FT_BLENDER9Blends two inputs together.
VN_M_FT_CLAMP10Clamps input to a minimum or maximum value.
VN_M_FT_MATRIX11Transforms input through a matrix.
VN_M_FT_RAMP12Interpolates in a table.
VN_M_FT_ANIMATION13Interpolates in a table.
VN_M_FT_ALTERNATIVE14Allows implementation to select between two alternatives.
VN_M_FT_OUTPUT15The root of each material fragment graph, the final output.

Table 2-3 presents the defined fragment types. It mentions the purpose of each one, including its input fields and what operation it performs to generate its emitted color. Click the fragment name to jump into the table below, for a more detailed explanation.

These are the types of output fragment that are currently defined:

color

The tree defines surface color. This is the most common use.

displacement

Displacement of a surface. Gives a displacement along the surface normal, with a displacement distance exactly equal to the average of the sum of the components of the triplet reaching the output fragment. In other words, the distance is (R+G+B)/3. This should be done in the coordinate space of the geometry being displaced.

audio

This is pending, and has not yet been given a final interpretation.

Table 2-3. Material Node Fragment Type Descriptions

NameDescription
Color

The color fragment emits a single constant floating point triplet, generally used to represent a RGB color. It is defined by three simple fields:

real64 red

The red component of the color being emitted by this fragment.

real64 green

The green component of the color being emitted by this fragment.

real64 blue

The blue component of the color being emitted by this fragment.

Light

The light fragment represents the amount of incoming light at a given point on a surface. It does not compute any view-dependent reflective properties of the surface, unless the BRDF field is used. The normal falloff ranges from zero to one, and defines the micro-geometry of the surface. A value of zero represents a perfectly flat surface, while a value of one represents a surface whose normals are randomly distributed.

enum type

The type of light computation the fragment represents. See Table 2-4 below.

real64 normal_falloff

Describes the smoothness of the surface.

node brdf

A node.

string brdf_r

A red something.

string brdf_g

A green something.

string brdf_b

A blue something.

Table 2-4. Light Types

Type NameValueDescription
M_LIGHT_DIRECT0The light falling directly on to a surface.
M_LIGHT_AMBIENT1The environment's ambient light.
M_LIGHT_DIRECT_AND_AMBIENT2Both direct and ambient light, added together.
M_LIGHT_BACK3The light that falls upon the back side of the material.

Reflection

This fragment represents a view-dependent perfect reflection computation from the evaluation point. The normal fall-off describes the micro-geometry in the same manner used by the light fragment.

real64 normal_falloff

Something.

Transparency

This fragment represents the properties of the surface that is behind the evaluation point. The refraction index represent how light is bent when passing through the surface, and the normal fall-off describes the micro-geometry just as in the light and reflection fragments.

real64 normal_falloff

Something.

real64 refraction_index

The refraction index of the material. Obviously not trivial to implement.

Volume

This fragment represents the volume of air between the light source and the point on the surface being shaded. It allows you to model non-clear air, by specifying a color that will be weighted in according to the distance travelled through the volume.

real64 diffusion

real64 col_r

real64 col_g

real64 col_b

View

This fragment simply generates a vector pointing from the point at the surface, directly towards the viewing position. It can be thought of as the surface's normal, transformed by the view matrix. For a point on the surface facing straight towards the camera, it will be (0, 0, 1). For a face facing to the left, it will be (1, 0, 0), and so on.

The fragment itself is empty, i.e. it has no parameters.

Geometry

The geometry fragment allows a material to reference properties defined in a geometry node. Any layer can be referenced, integer layers will be converted to normalized floating-point (by dividing with the maximum for the type in question). If an XYZ-type layer is being referenced, the values will be mapped to the RGB data space fragments use trivially (X becomes red, Y becomes green, and Z becomes blue). These are the fields of the fragment:

string layer_r

Which layer to use as source of red-channel values.

string layer_g

Which layer to use as source of green-channel values.

string layer_b

Which layer to use as source of blue-channel values.

There is no node reference in this fragment; this is because the layers being referenced are always (implicitly) taken to be in the current object's geometry node. This is typically the only practical approach anyway, since e.g. UV-mapping data must be closely coupled to the geometry data in order to be applicable; referencing layers in the same node helps ensure this.

Texture

The texture fragment uses the incoming color as a point in 3D space mapped onto a bitmap, and returns the value of the pixel at that point. It is used, with the geometry fragment, to express plain old texture-mapping. It has the following fields:

node bitmap

A bitmap node to read texture data from.

string layer_r

Which layer to use as source of red-channel values.

string layer_g

Which layer to use as source of green-channel values.

string layer_b

Which layer to use as source of blue-channel values.

boolean filtered

Is the texture to be filtered when viewed up close?

fragment control

The ID of a fragment whose output is used as the mapping, see above.

Noise

The noise fragment takes a single input color, and uses it as a lookup in a noise function. These are the types of noise currently supported:

Table 2-5. Noise Fragment Types

Type NameValueGenerated Noise
M_NOISE_PERLIN_ZERO_TO_ONE0Noise distributed in the numerical range [0,1] inclusive.
M_NOISE_PERLIN_MINUS_ONE_TO_ONE1Noise distributed in the numerical range [-1,1] inclusive.
M_NOISE_POINT_ZERO_TO_ONE2Noise, in range [0,1] inclusive.
M_NOISE_POINT_MINUS_ONE_TO_ONE2Noise in range [-1,1] inclusive.

enum type

The type of noise to generate. A value from the table above.

fragment mapping

Input coordinate that is looked up in (or fed to) the noise function.

Blender

The blender fragment takes two input colors A and B (and sometimes a control input), and blends them using a function chosen from the following list:

Table 2-6. Blender Fragment Types

Type NameValueFunction
M_BLEND_FADE0A * control + B * (1 - control)
M_BLEND_ADD1A + B
M_BLEND_SUBTRACT2A - B
M_BLEND_MULTIPLY3A * B
M_BLEND_DIVIDE4A / B

enum type

The type of blend to produce. One of the values listed above.

fragment data_a

The "A" source data.

fragment data_b

The "B" source data.

fragment control

The "control" data needed for the M_BLEND_FADE mode.

Clamp

The clamp fragment limits its input value, by computing the min() or max() function on the input and a constant. It is useful for instance to eliminate negative numbers from blending equations. The function is computed separately for each of the three channels.

Note

It is easy to confuse oneself when thinking about the clamp fragment. It helps to just keep in mind that it computes the standard min() or max() function, and nothing else. For instance, to make sure an input is kept to at most (0.5, 0.5, 0.5), set the clamp's min value to true, thus computing the min() function, which has the desired result.

boolean min

If true, the fragment computes the min() function, else it computes max().

real64 red

Red component of limit value.

real64 green

Green component of limit value.

real64 blue

Blue component of limit value.

fragment data

The input data that is to be clamped.

Matrix

The matrix fragment runs its input values through a 4x4 transformation matrix. Since the data passed between fragments is defined to be only triplets, they are considered extended with a fourth element with the value zero for these purposes. This element is then dropped again, since the data flowing between material fragments is only three components (RGB color). Of course, you can also think of it as just ignoring the last row and column of the matrix, and doing the operation on the 3x3 upper-left sub matrix.

The operation is a post-multiplication of the matrix by the color, e.g. output = matrix × color.

array of real64 matrix

The matrix itself, defined as 16 floating point values in row-major order.

fragment data

The input data to transform.

Ramp

A ramp (or curve) defined as an array of (position,color) tuples. It takes a color as input, and selects a single channel. The value of that channel is then used to do an interpolating look-up in the ramp, and the resulting color is emitted. A ramp essentially maps a one-dimensional input value into the three-dimensional color space.

Table 2-7. Ramp Fragment Types

Type NameValueRamp Interpolation
M_RAMP_SQUARE0Do no interpolation, just pick whatever value is closest in the ramp.
M_RAMP_LINEAR1Interpolate linearly between neighboring ramp values.
M_RAMP_SMOOTH2Interpolate bi-linearly between ramp elements.

Table 2-8. Ramp Channel Types

Type NameValueChannel Selection
M_RAMP_RED0Use the red component of incoming values to do the look-up.
M_RAMP_GREEN1Use the green component of incoming values to do the look-up.
M_RAMP_BLUE2Use the blue component of incoming values to do the look-up.

enum type

The type of interpolation desired in this ramp. Must be a value from Table 2-7 above.

enum channel

Which channel of the input should be used to do the look-up. Must be a value from Table 2-8 above.

array of (real64 position,red,green,blue) ramp

The ramp data itself. A maximum of 48 data points can be specified in a single ramp.

Animation

string label

Alternative

This fragment specifies two inputs, and allows the parser to select one and ignore the other. The most preferable path should always be specified as the one labeled A. The intent is to allow e.g. simpler materials to be defined in an alternative path. It is not defined how a shading implementation is supposed to chose between the two, it is left up to the implementor.

fragment alt_a

Alternative path A, the most preferable one.

fragment alt_b

Alternative path B, the least preferable one.

Output

The output fragment serves as the root for a material tree, and must be present in a material node in order for it to have any effect. It is defined by the following fields:

string type

What type of surface property is described by this output fragment. See above for a list of the defined, well-known, output types.

fragment front

The ID of the fragment which defines the surface property for the front side of polygons using this material.

fragment back

The ID of the fragment which defines the surface property for the back side of polygons using this material.

If the front field is given a valid, non-zero value, any surface using this material will show it on its forward-facing side. If the back field is given a valid, non-zero value, it will show up on the backward-facing sides. If front equals back and is the ID of a valid fragment, the material will be double-sided. Leaving either front or back set to zero (an invalid fragment ID) or set to an invalid value will make the corresponding side of surfaces invisible.

2.7.2. Examples

This section contains a set of example fragment graphs, to illustrate how the various pieces of functionality can be used together to create various actual materials.

Example 2-2. Plain Gray

Figure 2-2. A Plain Gray Material

Figure 2-2 shows a simple two-fragment material. This is about as simple as a material can become, since a lone output fragment is of little use. The added color fragment provides a constant medium-gray color for the entire surface. This material will not be very realistic, for example it will not react to incoming light at all.

The output fragment does not specify a value for the back field; meaning it's single-sided (surfaces using this material will not be visible from their back side).