A light in mental ray defines the location or direction within the 3D universe for light shaders, which get called when another shader calls mi_sample_light(). In the same way that an object is a scene entity with some well-defined basic features, a light is a data structure inside mental ray with a variety of fields (origin, direction, spread, area samples, etc.) some of which are required and some optional, depending on light type (spot light, area light, etc.). Some of the fields are:
• origin
• direction
• spread
• visible
• shadowmap
All of these parameters are accessible from within the shader by calling mi_query() with a light-related query code. For more information about querying for light parameters, see Getting Light Parameters.
Any parameter not in the basic light definition are part of your shader's parameter structure. For a light shader these would typically include color and falloff profile among other things. To access these parameters your shader should use the mi_eval_() functions.
This section contains the following topics:
• Setting Diffuse Only and Specular Only Attributes
In Autodesk Softimage, a light shader is connected to the light shader input of a light primitive.
The light primitive contains information, such as the type of light, the spread angle, shadow map settings, and photon settings.
The light shader can get this information from the light primitive using mi_query().
// state->light_instance is the miTag of the light instance // we need to get the miTag of the actual instanced item (the light element) miTag realLight; mi_query( miQ_INST_ITEM, NULL, state->light_instance, &realLight ); // Get the light type miInteger lighttype; mi_query( miQ_LIGHT_TYPE, NULL, realLight, &lighttype );
In Softimage, you can specify which lights affect an object. Shaders that use the lights in their calculations must respect this list.
To get the list of lights that the object is influenced by, add an array of lights to the shader:
Parameter "lights" input
{
title = "Light List";
guid = "{850C8000-119F-11D5-AE9A-00A0C96E63E1}";
ui "mapping" = "{38D56C23-8C0D-11D0-857D-00A02417D029}";
texturable = off;
inspectable = off;
type = array
{
Parameter "lights" input
{
title = "Light";
guid = "{850C8001-119F-11D5-AE9A-00A0C96E63E1}";
ui "mapping" = "{38D56C23-8C0D-11D0-857D-00A02417D029}";
texturable = off;
type = light;
}
};
}
The interface mapping lines, bold in the code above, signals to Softimage that the light list needs to be passed in. In the shader implementation, the light list will require three parameters in the parameter block.
For example:
typedef struct {
...
miInteger i_lights;
miInteger n1];
...
} my_shader_params;The data in the array is accessed using the same method as described in Getting a List of Objects.
Setting Diffuse Only and Specular Only Attributes
In Softimage, you can set lights to affect different portions of the lighting calculation. Normally, a lighting model, such as Phong, computes a diffuse component and a specular component as part of the lighting calculation. However, users can specify that a light should not contribute to the diffuse component. All four combinations (diffuse light, specular light, both, neither) are acceptable.
To pass this information to the shaders, Softimage associates a piece of user data with the light. The shader can then extract this user data from the light, and perform the appropriate calculations.
To find the user data, the shader must ask for the head of the list of user data associated with the light. The shader then searches through this list for the user data with the magic number XSIMR_LIGHTDATA_LABEL. If it finds it, it extracts the settings. If it does not find the data, it implies that both specular and diffuse computations should be performed.
Below is a snippet of code which extracts the flags.
/*----------------------------------------------------------------------*/ /* This code takes the tag of a light, and determines whether the light */ /* is specular, diffuse, both, or neither. */ void GetLightAttributes(miTag in_light, miBoolean *out_dodiffuse, miBoolean *out_dospecular) { miTag lightprim = miNULLTAG; miTag l_tUserData; if (mi_db_type(in_light) == miSCENE_INSTANCE) { /* We are interested in the attribute of the light primitive, */ /* and not of the instance */ mi_query(miQ_INST_ITEM, NULL, in_light, &lightprim); } else { lightprim = in_light; } /* Defaults: if no userdata is found, it implies there is nothing */ /* special about the light. */ *out_dodiffuse = miTRUE; *out_dospecular = miTRUE; if (mi_query(miQ_LIGHT_DATA, NULL, lightprim, &l_tUserData)) { /* We have user data */ /* Look for the first one with the correct magic number */ while (l_tUserData !=miNULLTAG) { /* Get the magic number of this piece of user data */ miUint l_magic; mi_query(miQ_DATA_LABEL, NULL, l_tUserData, &l_magic); /* Compare the magic number against the magic number of the */ /* light attribute user data */ if (l_magic == XSIMR_LIGHTDATA_LABEL) { /* We have found the light attribute user data */ break; } /* go to next data in user data list*/ if (!mi_query(miQ_DATA_NEXT, NULL, l_tUserData, &l_tUserData)) l_tUserData = miNULLTAG; } if (l_tUserData != miNULLTAG) { /* We found the light user data */ xsimrLightData *l_ud; /* Get the actual data, and extract the settings */ mi_query(miQ_DATA_PARAM, NULL, l_tUserData, &l_ud); *out_dodiffuse = (l_ud->flags & XSIMR_LF_DIFFUSE)?miTRUE:miFALSE; *out_dospecular = (l_ud->flags & XSIMR_LF_SPECULAR)?miTRUE:miFALSE; } }
Autodesk Softimage v7.5