Translation of Texture Map and Materials

Given a 3ds Max texture map plug-in derived from class TexMap or Material plug-in derived from Mtl, and a mental ray shader (with a DLL and .mi file) the following steps describe how to control how the plug-in is made compatible with 3ds Max.

Step 1: Inherit from imrShaderTranslation to enable custom shader translation for a TexMap or from imrMaterialPhenomenonTranslation for a Mtl class.

Step 2: Implement InterfaceServer::GetInterface() to return a pointer to the plug-in as an imrShaderTranslation for a TexMap:

BaseInterface* YourTexmapPlugin::GetInterface(Interface_ID id) {
    if(id ==  IMRSHADERTRANSLATION_INTERFACE_ID)
        return static_cast< imrShaderTranslation*>(this); else
        return NULL;
}

or to a imrMaterialPhenomenonTranslation for a Mtl:

BaseInterface* YourMaterialPlugin::GetInterface(Interface_ID id) {
    if (id ==  IMRMTLPHENTRANSLATION_INTERFACE_ID) {
        return static_cast< imrMaterialPhenomenonTranslation *>(this);
    }
    else {
        return NULL;
    }
 

Step 3: Implement imrShaderTranslation::GetMRShader() to return an instance of the shader to which you want your texture plug-in to translate to. Use the interface imrShaderCreation to instantiate the shader and return a pointer to it.

Note: if you create instances of several shaders (which is possible if you are translating to a tree of shaders rather than a single shader), then make references to these shaders (through the Reference system). This is necessary since only the root shader will be passed on to the imrShaderTranslation::TranslateParameters() method. Then, return the root shader.

If you are writing a material you will return a material phenomenon (i.e. a shader which derives from class Mtl). You may either create an instance of your own material phenomenon or, alternatively, you may create an instance of the material phenomenon called "max_default_mtl_phen" (see its declaration in 3dsmax.mi). This phenomenon is treated differently by 3ds Max, it will automatically be converted to a generic mental ray material. Thus, mental ray will see it as a generic material instead of a material phenomenon. You can use the imrShaderTranslation::TranslateParameters() method to assign the proper material/shadow/photon/etc. shaders to the "max_default_mtl_phen" shader.

Step 4: If you make any references to shaders in imrShaderTranslation::GetMRShader(), then you must release them in imrShaderTranslation::ReleaseMRShader() using SetReference(NULL). This allows freeing up memory after rendering. If you didn't make any references to shaders in step 3, then the implementation is empty. This is an optional step, meant to release memory. It won't hurt if you don't release your shaders here, unless they use a lot of memory.

Step 5: Implement imrShaderTranslation::NeedsAutomaticParamBlock2Translation() to return true if your shader parameters are implemented as compatible IParamBlock2 parameters and you want to your shader to be translated automatically, or false otherwise. If automatic translation is not possible, then manual translation is possible. See Automatic Translation for more information.

Step 6: Implement imrShaderTranslation::TranslateParameters() to translate parameters manually. It can be used alongside automatic parameter translation, to translate some parameters automatically and some manually, or by itself, to translate all parameters manually. It is very important that you store the validity interval of your manual translation into the "valid" parameter. The method imrShaderTranslation::TranslateParameters() is only called for the first frame, and then for each frame where it is invalid.

All values that you store in the parameter block of the shader must be set at time 0. That is, any call to IParamBlock2::SetValue() must not pass a time value other than zero. When translating the parameters of the shader, 3ds Max will only use values from time 0.

Step 7: Implement imrShaderTranslation::GetAdditionalReferenceDependencies(). Most plug-ins will do nothing in this method.

Before 3ds Max translates a plug-in, it translates the following first:

Let's use a simple case as an example: Assume you have implemented a simple texture map which contains two sub-texture maps. Those two sub-texture maps must exist in the mental ray database before your plug-in is itself entered in the mental ray database.

If your two sub-texture maps meet any of the three criteria above are either sub-references of your plug-in, are contained in a parameter block belonging to your plug-in, or are sub-texture maps of your plug-in, then they will automatically be translated and you don t need to do anything in imrShaderTranslation::GetAdditionalReferenceDependencies().

If you have sub-texture maps that are not found using the search mechanism then the translator will fail to assign them to your shader (your shader will get a miNULLTAG as the parameter values). In this case, you must pass references to those two sub-texture maps to the translator.

Step 8: Implement the IMtlRender_Compatibility_MtlBase interface to tell 3ds Max that your plug-in is compatible with the mental ray renderer.

  1. Derive the class descriptor of your plug-in from class IMtlRender_Compatibility_MtlBase.
  2. Add a call to IMtlRender_Compatibility_MtlBase::Init() in the constructor of the class descriptor.
  3. Implement IMtlRender_Compatibility_MtlBase::IsCompatibleWithRenderer(). This method should check the class ID of the renderer and return true if the plug-in is compatible with this renderer. The class ID of the mental ray renderer is MRRENDERER_CLASSID.

Texture Map Specific Steps

The following steps apply only to translation of texture maps.

Implement the imrShaderTranslation_ClassInfo interface to provide "apply type" information on your shader to 3ds Max. By default (if you don't implement this interface), your shader will be considered as having the "texture" apply type.

  1. Derive the class descriptor of your plug-in from imrShaderTranslation_ClassInfo.
  2. Add a call to imrShaderTranslation_ClassInfo::Init() in the constructor of the class descriptor.
  3. Implement imrShaderTranslation_ClassInfo::GetApplyTypes() to return all the apply types that are valid for your shader. The apply types is a combination of flags from the enumeration imrShaderClassDesc::ApplyFlags.

Material Specific Steps

The following steps apply only to translation of materials.

  1. Implement imrMaterialPhenomenonTranslation::SupportsMtlOverrides(). This is used by 3ds Max to determine whether your material plug-in can be assigned the "mental ray connection" custom attribute. This custom attribute is an additional rollup in the material editor that allows overriding particular shaders in the material.

    Note that, to support material overrides automatically, your shader must translate itself to the "max_default_mtl_phen" phenomenon. Otherwise, you'll have to support the overrides yourself by querying the interface class imrMaterialCustAttribon the custom attributes of the materials.

  2. Implement imrMateralPhenomenonTranslation::InitializeMtlOverrides(). You don't need to provide an implementation for this if imrMaterialPhenomenonTranslation::SupportsMtlOverrides() returns false. This is used to initialize the material overrides when they are assigned to the material. You don't necessarily have to do anything here.