Keywords: main

Next: 3.8 Material Shaders Up: 3. Using and Writing Previous: 3.6 Parameter Assignments and

# 3.7 Shader Versioning

The parameter set of a shader must always be correctly described by its declaration in the .mi scene file. It is a common source of errors to have a mismatch between the .mi and the .c shader parameters. This can lead to incorrect rendering results but can also cause shader crashes, for example if the shader mistakes a floating-point number for an array length.

For this reason it is highly recommended to attach version numbers to both the .mi declaration and the shader itself. Version numbers are positive integers, and should begin with 1 (0 is the default if the version number is missing). For example, the .mi declaration of a shader myshader might be defined as:

        declare shader
            color "myshader" (parameters)
            version 42
        end declare

There are two ways to ensure that the version number is correct. The recommended method is writing a pseudo-shader that provides the version number:

         DLLEXPORT int myshader_version(void) {return(42);}

         DLLEXPORT miBoolean myshader(
            miColor         *result,
            miState         *state,
            struct myshader *paras)
         {
            ...
         }

Before mental ray calls a shader for the first time, just before looking for its initialization shader (whose name would be `myshader_init`), mental ray checks whether a function exists whose name is the shader name followed by `_version`. If it does, it is called and the version number is compared with the version number in the .mi declaration. If there is a mismatch, an error message is printed. If the version shader does not exist, a warning message is printed.

The second method for shader version comparison is an explicit comparison in the shader using mi_query:

         #define MYSHADER_VERSION 42

         DLLEXPORT miBoolean myshader(
            miColor         *result,
            miState         *state,
            struct myshader *paras)
         {
            int             version;

            mi_query(miQ_DECL_VERSION, state, 0, &version);
            if (version != MYSHADER_VERSION)
                mi_error("myshader: wrong declaration");
            ...
         }

It is actually preferable to do this in the initialization shader to reduce the overhead of checking the version number every time the shader is called.

It is very important to always increment the version number every time the shader parameters change. Problems introduced by mismatches are hard to find, especially if the shader versions on client and server hosts do not agree.

The following sections discuss the various types of shaders, and how to write custom shaders of those types. Basic concepts are introduced step by step, including supporting functions and state variables supplied by mental ray. All support functions are summarized at the end of this chapter.

Next: 3.8 Material Shaders Up: 3. Using and Writing Previous: 3.6 Parameter Assignments and