Geometry Shaders

Geometry shaders do not really shade anything, they create scene elements, primarily geometric objects. For this purpose, they use a special geometry shader API that is analogous to the statements of the .mi scene definition language. This chapter describes this API, and how geometry shaders use it.

Geometry shaders can be used in two places: in instance definitions that reference a shader instead of an object, light, camera, or instance group:

instance "name"  
    geometry function  
    ...  
end instance  

or in phenomena, where they can be attached to the geometry root:

declare phenomenon  
    ...  
    geometry function  
    ...  
end declare  

In either case, the geometry shader is evaluated during scene preprocessing before any other operation such as rendering starts. The geometry shader is expected to create an object, light, camera, or instance group and add the tag of the created element to the result. The result pointer passed as its first argument always has the type miTag *, and the shader must be declared as

declare shader  
    geometry "shader_name" ("parameter_decl")  
    ...  
end declare  

If result is a null tag, the created element can be returned directly using this pointer, otherwise the geometry shader must check whether the type of the item to which result refers is miSCENE_GROUP. If it refers to an instance group, the created entities can be put into this group, otherwise the shader must create the group and put the element to which result refers together with the entities created by the geometry shader into the instance group. The newly created instance group must be returned in result in this case. This ensures that geometry shaders always return either an object or an instance group, and that they can be chained such that the end result is a group. There is a shader interface function available for adding scene entities to result which takes all the above rules into account; refer to mi_geoshader_add_result.

Creation of geometry requires an altogether different set of shader interface functions. The shader is basically doing the same thing that an object or other definition expressed in the .mi language is doing, and must have the same functionality available to it. In fact, the shader interface functions for geometry shaders closely model the .mi language features: there are begin/ end functions for most top-level entities and complex sub-entities, and various helper functions to create and attach complex information. Many of these return pointers to the created data structures that let the geometry shader store primitive data directly without the use of a shader interface function.

Geometry shaders must include geoshader.h after shader.h.

This chapter provides an example and lists all shader interface API functions and data structure declarations available to geometry shaders. It does not explain the structure and order of specific API calls needed to create a scene. Refer to chapter scenechapter for the sequence of operations necessary to create a scene element, and to appendix A for the correspondence between API calls and the entities in the scene description language they create.

In any case, writing geometry shaders is far more complex than writing another type of shader. Although a geometry shader has free run of the entire scene database, and is free to copy-and-alter or create any part of it, it is generally a good idea to avoid doing too much with them. Instead, it is usually preferable to pass objects, materials, and shaders as input parameters instead of creating entire graphs in geometry shaders, although this is possible and sometimes needed in geometry shaders used in phenomena. Geometry shaders must never modify existing parts of the scene because this will confuse future incremental changes and scene traversal during preprocessing, which geometry shaders are part of. Instead, the element to be modified should be passed to the geometry shader as a parameter of type geometry, and be used as a template to create a new, modified element.

All geometry shader API calls and data structures may only be used in geometry shaders, not any other type of shader. Conversely, no regular shader interface function related to rendering may be used in a geometry shader because it is called before rendering begins. Geometry shaders are called during the same stage as displacement shaders, but before the displacement shaders of objects created by this geometry shader.

mental ray 3.0 allows a geometry shader to create a placeholder object that contains no geometry, but a bounding box (and optionally a motion bounding box and a maximum displacement), and a callback installed with mi_api_object_callback. When mental ray hits the bounding box of this placeholder, it will call the callback, which must then build the same object again, only this time with the real geometry instead of just installing the callback. Placeholder objects may contain only a single object group. This has the advantage that objects are not created unless, and when, they are actually needed. When memory runs out, mental ray 3.0 can free up a lot of memory by deleting the object - if necessary it can always call the callback again to restore it. Finally, If there are several such placeholder objects, and multiple CPUs, mental ray can process callbacks in parallel. Placeholder objects are highly recommended for complex geometry that would otherwise block a large chunk of memory.

Copyright © 1986-2011 by mental images GmbH