Keywords: main

Next: 2.5 Phenomena Up: 2. Scene Description Language Previous: 2.3 Shader Lists

# 2.4 Shader Graphs

Instead of assigning a constant value to a parameter in a shader definition, it is possible to assign a shader:

        "parameter_name" = "shader_name"

For parameters assigned in this way, no value is stored in the shader definition. It is obtained by calling shader_name at runtime. For example, if the ambient parameter of a material shader has the constant value `1 0 0`, it is always red, but if another shader is assigned to it that other shader is called when the material shader asks for the value using the mi_eval function or one of its derivatives. The other shader could be a texture shader, for example, resulting in a textured ambient value.

The return type of the assigned shader must agree with the parameter type. If the return type of the assigned shader is `struct`, it is possible to select a structure member by appending a period and the name of the struct member to the shader name. Consider the following assignment:

         declare shader
            color "phong" (color "ambient",
                           color "diffuse",
                           color "specular")
            version 1
         end declare

         declare shader
            struct {color "a", color "b"}
                  "texture" (color texture "picture")
            version 1
         end declare

         color texture "fluffy" "/tmp/image.rgb"

         shader "map" "texture" (
            "picture"   "fluffy")

         shader "mtlsh" "phong" (
            "ambient"   0.3 0.3 0.3,
            "diffuse"   = "map.a",
            "specular"  = "map.b")

This defines a material shader that does not support texturing in any way because it has no parameters of type `shader` or `color texture`. Yet, shader assignments allow its diffuse and specular components to be textured without the `phong` shader being aware of it. Whenever `phong` accesses its ambient parameter value by calling mi_eval, it gets a constant color 0.3 0.3 0.3, but when it accesses its diffuse or specular colors a call to the named shader `map` results (which actually calls shader `texture`), whose result is then returned to the `phong` shader.

In this example, the `map` shader returns two colors `a` and `b`, which are selected in the shader assignment by appending `.a` and `.b` to `map`. (For this reason periods should be avoided in parameter names.) If the shader had returned only a single color, only `"map"` would have been assigned, without appending a period and a structure member name.

In the example, `map` is assigned twice. Obviously it is not desirable to actually call it twice, because the first call will already have set both its `a` and `b` return values. After the first call from a shader, caches the return value to avoid further calls. As soon as the shader `phong` returns, the cache is discarded to ensure that the next call to `phong`, most likely with a different state, calls `map` instead of using a stale cache.

Note that shaders that support shader graphs must use the mi_eval function to access their parameters. This was done to ensure that only those assigned shaders whose values are actually used are evaluated. For example, a material shader that has two color parameters, one for the front and one for the back side of the surface, will access only one of its parameters by using mi_eval only once.

To see how the phong shader is implemented as a C shader, see the section ``Parameter Assignments and mi_eval'' in chapter .

The advantage of shader assignment is that it is not necessary to write shaders to accept procedural values. Without shader assignments, a simple Phong material shader would need parameters of type `shader` or color texture in addition to the standard ambient, diffuse, and specular parameters. Shader assignment allows writing small, reusable `` base shaders'' that can be easily combined into powerful shader graphs, instead of writing large monolithic shaders that are hard to modify and inflexible to use.

The third form of parameter assigning using the `interface` keyword is available only inside phenomena, which will be discussed next.

Next: 2.5 Phenomena Up: 2. Scene Description Language Previous: 2.3 Shader Lists