Supporting Render Channels

Render channels allow users to output multiple images for each frame, with each image containing different data. The Scene Render Options property page includes a tab that lists all the render channels in the scene.

Render channels use the new multiple framebuffer mechanism provided in mental ray 3.4 and later.

At render time, Softimage creates all the required framebuffers to hold the render channel data and a userdata block that gets linked to the mental ray render options. The userdata is required since mental ray does not provide a way of naming the framebuffers. The userdata contains a mapping table between the name of each active pass channel and the framebuffer index to use for it.

| Only the render channels actually in use will be in the render channel user data. For passes, this includes the render channels required by the pass's framebuffers and, for the render region, only a single render channel is active at a time (which, if the main buffer is being viewed, can result in no render channel userdata being pushed at all, since no mapping is required for the main buffer).

Image Types

This table of render channel image type names and the matching mental ray image types. The channel names are case-insensitive. mental ray treats each image type as a separate channel format and bit depth. Softimage allows (in most cases) the channel type and bit depth to be selected individually.

Render channel image names | mental ray Image Type
"Color" | miIMG_TYPE_RGBA miIMG_TYPE_RGBA_16 miIMG_TYPE_RGBA_H miIMG_TYPE_RGBA_FP miIMG_TYPE_RGB miIMG_TYPE_RGB_16 miIMG_TYPE_RGB_H miIMG_TYPE_RGB_FP
"RGBA" | miIMG_TYPE_RGBA miIMG_TYPE_RGBA_16 miIMG_TYPE_RGBA_H miIMG_TYPE_RGBA_FP
"RGB" | miIMG_TYPE_RGB miIMG_TYPE_RGB_16 miIMG_TYPE_RGB_H miIMG_TYPE_RGB_FP
"RGBE" | miIMG_TYPE_RGBE
"Alpha" or "A" | miIMG_TYPE_A miIMG_TYPE_A_16 miIMG_TYPE_A_FP
"Intensity" or "S" | miIMG_TYPE_S miIMG_TYPE_S_16 miIMG_TYPE_S_FP
"Depth" or "Z" | miIMG_TYPE_Z
"Motion" or "M" | miIMG_TYPE_M
"Normal" or "N" | miIMG_TYPE_N
"Tag" or "T" | miIMG_TYPE_TAG

mental ray Shader Code

The following is some (very basic) mental ray code to extract a named render channel. Ideally, a shader should store the information from is_channel_enabled in a shader local data created in the _init function of the shader.

    #include <shader.h>
    #include <xsi_miuserdata_defs.h>
    #include <string.h>

    #ifdef WIN32
    #define strcasecmp stricmp
    #endif

    miBoolean is_channel_enabled
    (
       miState    *state,
       char    *channel_name,
       int      *fb_id
    )
    {
       miTag    data = state->options->userdata;

       /* Find the render channel userdata */
       while( data )
       {
         miUint label;

         mi_query( miQ_DATA_LABEL, NULL, data, (void *)&label );
         if( label == XSIRenderChannel_Magic )
         {
           XSIRenderChannelsUD *rc;
           int i;

           mi_query( miQ_DATA_PARAM, NULL, data, (void *)&rc );

           for( i = 0; i < rc->n_channel; i++ )
           {
             XSIRenderChannel  *pChannel = &rc->channel[ i + rc->i_channel ];
             const char     *szName;

                    szName = (const char *)mi_db_access( pChannel->name );

             if( strcasecmp( szName, channel_name ) == 0 )
             {
               mi_db_unpin( pChannel->name );

              *fb_id = pChannel->fb;
               return( miTRUE );
             }
             mi_db_unpin( pChannel->name );
           }
           return( miFALSE );
         }
         mi_query( miQ_DATA_NEXT, NULL, data, (void *)&data );
       }

       return( miFALSE );
     }

     /* The shader is set as a pass-through shader and so the parameter block
        consists of a single color only. The shader records the incoming color
        and the motion at current intersection point */
    miBoolean render_channel( miColor *result, miState *state, miColor *p )
    {
       int      fb_color, fb_motion;

       *result = *mi_eval_color( p );

       if( is_channel_enabled( state, "ChannelOne", &fb_color ) )
       {
         mi_fb_put( state, fb_color, result );
       }

       if( is_channel_enabled( state, "ChannelTwo", &fb_motion ) )
       {
         miVector    motion = { 0.0f, 0.0f, 0.0f };

         /* Get the motion vector in internal (world) space */
         if( state->motion.x != 0.0f &&
           state->motion.y != 0.0f &&
           state->motion.z != 0.0f )
           mi_vector_from_object( state, &state->motion, &motion );

         mi_fb_put( state, fb_motion, &motion );
       }

       return( miTRUE );
    }

Autodesk Softimage v7.5