This section only describes the representation of phenomena in the .mi language. The declaration of a phenomenon is very similar to the declaration of a shader, except that the keyword shader is replaced with phenomenon, and the addition of new optional statements in the declaration block:
declare phenomenon
[type] "phenomenon_name" (
type "parameter_name",
type "parameter_name",
...
type "parameter_name"
)
[ version versionint ]
[ shader "name" ...
[ material "name" ... end material
[ light "name" ... end light
[ instance "name" ... end instance
[ roots ]
[ options ]
end declare
For a description of version, shader, material, light, and instance definitions, see the corresponding section above; the syntax is identical to the one described there. The options are identical to the options described in the shader declaration section above. The roots are described below.
The phenomenon phenomenon_name declared with this statement is available for the definition of shaders just like a shader declared with a declare shader statement. Named and anonymous shader definitions can be derived from either type of declaration. Phenomena were designed to extend the concept of shaders, not replace it.
Phenomena, like shaders, have parameters. In the phenomenon case they are called `` interface parameters'' because they form the gateway between the rest of the scene and the internal implementation of the phenomenon. Interface parameters are what makes the phenomenon look like a simple shader to the named and anonymous shader definitions. Phenomena are implemented in terms of subshader nodes, each with their own parameters. Subshader parameters can be assigned from the interface using an assignment of the following form:
"parameter_name" = interface "ifname"
This looks similar to the shader assignments described above, but when the shader calls mi_eval on a parameter assigned to the interface of the phenomenon it is defined in, no shader is called but the value is obtained from the phenomenon interface. For example:
declare shader color "phong" (color "ambient", color "diffuse", color "specular") version 1 end declare declare phenomenon color "phong_phen" (color "col") version 1 shader "sub" "phong" ( "ambient" 0.3 0.3 0.3, "diffuse" = interface "col", "specular" 1.0 1.0 1.0) root = "sub" end declare shader "mtlsh" "phong_phen" ( "col" 1.0 0.5 0.0)
For the shader definition, the phenomenon phong_phen looks like a shader with a single color parameter col. Internally, it contains the definition of a simple shader sub with three parameters, two of which have constant values and one which takes its value from the interface. When the shader definition mtlsh is called from a material or elsewhere in the scene, it calls the phenomenon phong_phen with the value 1.0 0.5 0.0 for the interface parameter col. This value is propagated to the diffuse parameter of the shader sub during evaluation of the phenomenon.
It is important to distinguish parameter values, such as 1.0 1.0 1.0 for specular, from shader assignments, which begin with an ``='' sign. In particular, consider the shader parameter type shader: if a shader name is given as the value without ``='' sign, the named shader will be returned but not called by mi_eval. With an ``='' sign, mi_eval will call the shader and expect it to return another shader (so its return value must have type shader) which is then returned by mi_eval. The latter involves an indirection, and is not often used for parameters of type shader. This is a common mistake, and return type mismatches will result in mental ray warning messages.
When calling a phenomenon, all its parameters must pass through the interface. The shader sub and everything else defined inside the phenomenon block is visible only inside the phenomenon, and no names defined outside the phenomenon are visible to definitions inside the phenomenon. The interface is the only connection point between the inner and outer world. This encapsulation ensures the integrity and completeness of phenomena independently of the scene they are used in.
Phenomena may also contain material, light, and instance definitions in addition to shader definitions.
By convention, anonymous shader definitions should not be used in phenomenon declarations. There is no functional disadvantage in using anonymous shader definitions but it makes life difficult for graphical phenomenon editing tools like mental images' Phenomenon Creator, which uses shader names to label the icons and boxes that represent subshaders in its graph and browser views.
The return type of a phenomenon may be any type that is a valid return type for a shader.
The above example also illustrates a new option allowed in phenomenon but not shader definitions, the phenomenon root. There are several types of root statements:
root shader
root material "material_name"
geometry shader
volume shader
environment shader
lens shader
output shader
output ["type"] "format" [opt] "filename"
contour store shader
contour contrast shader
volume priority priorityint
environment priority priorityint
lens priority priorityint
output priority priorityint
All of these except one of the first two are optional. The first root statement specifies the primary root shader of a phenomenon that is called when the phenomenon is called. In the above example, the mtlsh shader, when called, calls the phenomenon phong_phen, which immediately calls its subshader sub because sub is specified in its root statement.
The root material variant creates a material phenomenon.
This type of phenomenon must be declared with the return type material. It is instanced normally with a shader statement,
which provides the interface parameter values. The resulting shader
is different from regular shaders; its name can be used everywhere
where a material name is valid. A regular phenomenon that does not
have type material and no root material statement, when
instanced using a shader statement, becomes a shader, not a
material. Material phenomena should be used instead of regular
phenomena if the phenomenon depends on not only assigning a single
shader, such as a material shader, but other material components
such as shadow shader, photon shader, volume shader etc. as well.
See page for an example of a material phenomenon.
In addition to the main root statement, other roots may be defined that reference shaders of other types:
Note that during rendering, only root (or root material in the material phenomenon case) has any significance because the others have been removed and added to the camera or the scene before rendering started. After rendering and output shading completes, all these changes are undone. Note that if the phenomenon is defined several times (using multiple shader statements or anonymous shader definitions that reference it), the roots other than the main root are added to the scene more than once. 2.2
The shader priority statements provide control over the the placing
of the specified shaders or shader lists in the corresponding shader
list in the camera. Shaders with greater priority numbers are appended
to shaders with smaller priority numbers, and hence execute later.
Shaders with no priority number have priority 0, so they get executed
before shaders with positive priority numbers.