User-Defined Shaders

mental ray comes with several of standard shader packages which allow to render a big variety of visual effects. In addition, user-defined shaders can be written and used for rendering. They are traditionally written in native computer languages like C or C++ and manually compiled and linked at runtime, or the source code can be passed to mental ray for automatic compilation and dynamic loading. Modern approaches may use the meta shading language MetaSL to write code in a standardized form which abstracts from specific renderers. MetaSL shaders including phenomena built on top if such shaders are directly supported by mental ray.

User-defined shaders can be used in place of any standard shader, redefining materials, textures, lights, environments, volumes, displacements and more.

MetaSL Shaders

mental ray supports shaders written in MetaSL language to be used for software rendering. This is handled by integrated support for automatic compilation and/or linking of MetaSL shaders on the target platform. For network rendering, compilation of the MetaSL shaders on slave or satellites is supported.

Native Shaders

The mental ray native shader interface uses C language conventions. Shaders written in C++ should use extern "C" constructs to access the interface. Care should be taken to to avoid known C++ performance pitfalls such as new or virtual class members. Even a small runtime overhead becomes significant if incurred millions of times per frame.

mental ray can link in user-defined shaders either as dynamic shared object (DSO or DLL, as plain object file, or in source form.

Every user-defined shader must be declared before it can be used. A declaration is a statement that names the shader, and lists the name and type of all its parameters.

Declarations may appear in the .mi scene description file, but are typically stored in an external file included at run time. Note that all code and link statements must precede the first declaration in the .mi file.

Available parameter types are boolean, integer, scalar, string, color (RGBA), vector, transform (4 × 4 matrix), scalar texture, color texture, vector texture, shader, material, geometry, and light. In addition to these primitive types, compound types may be built using struct and array declarations. Structs may be nested but arrays may not.

An instance of a shader can be created by creating a material, texture, light etc. that names a declared shader and associates a parameter list with values. Any parameter name that appeared in the declaration can be omitted or listed in any order, followed by a value that depends on the parameter type. Omitted parameters default to 0. Scalars accept floating point numbers, vectors accept one to three floating point numbers, and textures accept a texture name.

After a material, texture, light etc has been created, it can be used. Materials are used by giving their names in object geometry statements, and textures and lights are used by naming them as parameter values in other shaders, typically material shaders.

When the C function that implements a user-defined shader is called, it receives three pointers: one points to the result, one to global state, and one to a data structure that contains the parameter values. mental ray stores the parameter values in that data structure using a layout that corresponds exactly to the layout a C compiler would create, so that the C function can access parameters simply by dereferencing the pointer and accessing the data structure members by name. For this, it is necessary that a struct declaration is available in C syntax that corresponds exactly to the declaration in .mi syntax.

For details on user-defined shaders, refer to the Writing Shaders chapter.

Copyright © 1986, 2013 NVIDIA Corporation