Public Member Functions

ToneOperator Class Reference

Search for all occurrences

Detailed Description

See also:
Class SpecialFX, Class ToneOperatorInterface, Class IRendParams, Class RendParams, Class RenderGlobalContext, Class RenderMapsContext, Class ShadeContext, Class Interval.

Description:
This class is available in release 4.0 and later only.

This is the base class for the creation of Tone Operator plug-ins. A Tone Operator performs two functions:

1. It converts physically based values to RGB for filtering and display. The renderer calls the tone operator immediately after Mtl::Shade is called.

2. It balances physical and non-physical lighting.

The tone operator balances the physical and non-physical lighting by providing a scale relationship between them. The scale converts physical candelas to the non-physical value 1.0. Physically based objects in the 3ds Max scene use this scale to convert their values for use by the renderer and materials. The tone operator then converts the scaled value to RGB for display.

An example of this is the tone operator for a radiosity plug-in. 3ds Max works in a lighting space where values run from 0 to 1 and don't have any meaning. Pre-rendered Reflection maps, Refraction maps and self-illumination maps also use a 0 to 1 scale without any meaning. A radiosity plug-in introduces physical values to 3ds Max that range from 0 to 90000 for the sun.

So the question is "How do we mix these values with physical values?" One solution is to use a scale. Physical values are scaled to "3ds Max" values. Then they are processed by the shaders and materials, and then the scaled values are converted to RGB by ScaledToRGB.

So the PhysicalUnits, ScalePhysical and ScaleRGB are used to convert from 3ds Max lighting values to physical lighting values. We can use this to balance 3ds Max lights with physical lights, and to assign physical values to 3ds Max lights when we want to use them in a radiosity solution.

The tone operator may include a UI that allows the user to set the scale, or it can set the scale apriori. The scale is also used for reflection maps, which are usually implemented in 32 bit bitmaps. If the scale is set too high, reflection maps can show banding because of rounding errors. If the scale is set too low, reflection maps can wash out because of clipping values to 0...255.

The tone operator uses the standard Special Effects parameter dialog class for its user interface.

Note: typedef SFXParamDlg ToneOpParamDlg;

#include <toneop.h>

Inheritance diagram for ToneOperator:
Inheritance graph
[legend]

List of all members.

Public Member Functions

  ToneOperator ()
RefResult  NotifyRefChanged (Interval changeInt, RefTargetHandle hTarget, PartID &partID, RefMessage message)
  Receives and responds to messages.
SClass_ID  SuperClassID ()
  Retrieves a constant representing the type of the plugin.
IOResult  Save (ISave *isave)
IOResult  Load (ILoad *iload)
virtual BOOL  Active (TimeValue t)
virtual void  SetActive (bool active, TimeValue t)
bool  GetProcessBackground ()
void  SetProcessBackground (bool active)
bool  GetIndirectOnly ()
void  SetIndirectOnly (bool active)
virtual ToneOpParamDlg CreateParamDialog (IRendParams *ip)
virtual BOOL  SetDlgThing (ToneOpParamDlg *dlg)
virtual bool  IsPhysicalSpace () const
virtual void  Update (TimeValue t, Interval &valid)
virtual bool  BuildMaps (TimeValue t, RenderMapsContext &rmc)
virtual void  SubRenderSample (float energy[3])
virtual void  ScaledToRGB (float energy[3])=0
virtual float  ScaledToRGB (float energy)=0
virtual float  GetPhysicalUnit (TimeValue t, Interval &valid=Interval(0, 0)) const =0
virtual void  SetPhysicalUnit (float value, TimeValue t)=0
virtual void  ScalePhysical (float energy[3]) const =0
virtual float  ScalePhysical (float energy) const =0
virtual void  ScaleRGB (float color[3]) const =0
virtual float  ScaleRGB (float color) const =0
bool  CanInvert ()
void  RGBToScaled (float energy[3])
float  RGBToScaled (float energy)

Constructor & Destructor Documentation

ToneOperator ( ) [inline]

Member Function Documentation

RefResult NotifyRefChanged ( Interval  changeInt,
RefTargetHandle  hTarget,
PartID partID,
RefMessage  message 
) [inline, virtual]

Receives and responds to messages.

A plugin which makes references must implement a method to receive and respond to messages broadcast by its dependents. This is done by implementing NotifyRefChanged(). The plugin developer usually implements this method as a switch statement where each case is one of the messages the plugin needs to respond to. The Method StdNotifyRefChanged calls this, which can change the partID to new value. If it doesn't depend on the particular message& partID, it should return REF_DONTCARE.

  • For developer that need to update a dialog box with data about an object you reference note the following related to this method: This method may be called many times. For instance, say you have a dialog box that displays data about an object you reference. This method will get called many time during the drag operations on that object. If you updated the display every time you'd wind up with a lot of 'flicker' in the dialog box. Rather than updating the dialog box each time, you should just invalidate the window in response to the NotifyRefChanged() call. Then, as the user drags the mouse your window will still receive paint messages. If the scene is complex the user may have to pause (but not let up on the mouse) to allow the paint message to go through since they have a low priority. This is the way many windows in 3ds Max work.
Parameters:
changeInt - This is the interval of time over which the message is active. Currently, all plug-ins will receive FOREVER for this interval.
hTarget - This is the handle of the reference target the message was sent by. The reference maker uses this handle to know specifically which reference target sent the message.
partID - This contains information specific to the message passed in. Some messages don't use the partID at all. See the section List of Reference Messages for more information about the meaning of the partID for some common messages.
message - The message parameters passed into this method is the specific message which needs to be handled.
Returns:
The return value from this method is of type RefResult. This is usually REF_SUCCEED indicating the message was processed. Sometimes, the return value may be REF_STOP. This return value is used to stop the message from being propagated to the dependents of the item.

Implements ReferenceMaker.

                                             {return REF_SUCCEED;}
SClass_ID SuperClassID ( ) [inline, virtual]

Retrieves a constant representing the type of the plugin.

Returns:
A super class id that uniquely identifies the type (category) of the plugin. Note that several plugin classes can be of the same type, thus return the same super class id. Plugins are uniquely identified by their class ids. List of Super Class IDs.
See also:
SClass_ID

Reimplemented from ReferenceTarget.

IOResult Save ( ISave isave ) [inline, virtual]
Remarks:
Implemented by the System.

To facilitate naming atmospheric or rendering effects, a 'name' string has been added to the base class. This method should be called from the developers sub-classed Atmospheric or Effects plug-in to save the name.

Reimplemented from SpecialFX.

{ return SpecialFX::Save(isave); }
IOResult Load ( ILoad iload ) [inline, virtual]
Remarks:
Implemented by the System.

To facilitate naming atmospheric or rendering effects, a 'name' string has been added to the base class. This method should be called from the developers sub-classed Atmospheric or Effects plug-in to load the name.

Reimplemented from SpecialFX.

{ return SpecialFX::Load(iload); }
virtual BOOL Active ( TimeValue  t ) [inline, virtual]
Remarks:
Returns TRUE if the effect is active; otherwise FALSE.
Parameters:
TimeValue t

The time at which to check.
Default Implementation:
{ return FALSE; }

Reimplemented from SpecialFX.

virtual void SetActive ( bool  active,
TimeValue  t 
) [inline, virtual]
Remarks:
This method indicates whether the tone operator is active. The default implementation does not use the TimeValue t. The result of the default implementation can be retrieved using SpecialFX::GetActive. If you override this method and change the mechanism for storing this state, you should also override SpecialFX::GetActive so the correct state is returned.
Parameters:
bool active

A boolean indicating if the tone operator is active.

TimeValue t

The time at which the active check is made.
Default Implementation:
if (active ^ (TestAFlag(A_ATMOS_DISABLED) == 0)) {

if (active) {

ClearAFlag(A_ATMOS_DISABLED);

}

else {

SetAFlag(A_ATMOS_DISABLED);

}

NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

}
      {
        if (active ^ (TestAFlag(A_TONEOP_DISABLED) == 0)) {
            if (active) {
                ClearAFlag(A_TONEOP_DISABLED);
            }
            else {
                SetAFlag(A_TONEOP_DISABLED);
            }
            NotifyDependents(FOREVER, (PartID)PART_ALL, REFMSG_CHANGE);
        }
    }
bool GetProcessBackground ( ) [inline]
Remarks:
Returns the state of A_TONEOP_PROCESS_BG, indicating whether the ToneOperator will be processing the background.
{ return TestAFlag(A_TONEOP_PROCESS_BG) != 0; }
void SetProcessBackground ( bool  active ) [inline]
Remarks:
This method allows you to set A_TONEOP_PROCESS_BG.
Parameters:
bool active

TRUE to activate, FALSE to deactivate.
bool GetIndirectOnly ( ) [inline]
void SetIndirectOnly ( bool  active ) [inline]
virtual ToneOpParamDlg* CreateParamDialog ( IRendParams ip ) [inline, virtual]
Remarks:
This method creates the rollup pages in the render panel that lets the user edit the tone operator's parameters. You can use IRendParams::AddRollupPage and IRendParams::DeleteRollupPage to manage your rollup pages directly. Or, if your parameters are stored in a ParamBlock2 object, you can use CreateRParamMap2 and DestroyRParamMap2 to manage the rollups. You may return NULL, if no UI is required.
Parameters:
IRendParams *ip

Points to the render parameter dialog interface. You may call the methods of that class using this pointer.
Returns:
Pointer to the tone operator dialog.
Default Implementation:
{ return NULL; }

Reimplemented from SpecialFX.

{ return NULL; }
virtual BOOL SetDlgThing ( ToneOpParamDlg dlg ) [inline, virtual]
Remarks:
Implement this if you are using the ParamMap2 AUTO_UI system and the atmosphere has secondary dialogs that don't have the effect as their 'thing'. Called once for each secondary dialog for you to install the correct thing.
Parameters:
ToneOpParamDlg* dlg

Points tot he tone operator dialog.
Returns:
Return TRUE if you process the dialog, FALSE otherwise.

Reimplemented from SpecialFX.

{ return FALSE; }
virtual bool IsPhysicalSpace ( ) const [inline, virtual]
Remarks:
Returns a boolean which indicates if this tone operator really maps physical values to RGB. This method is provided so shaders can determine whether the shading calculations are in physical or RGB space.
Default Implementation:
{ return true; }
{ return true; }
virtual void Update ( TimeValue  t,
Interval valid 
) [inline, virtual]
Remarks:
This method is called once per frame when the renderer begins. This gives the tone operator the chance to cache any values it uses internally so they don't have to be computed on every pixel. But, this method should not be used to perform any very long tasks. This would be the likely method that caches the frames physical scaling value.
Parameters:
TimeValue t

The time at which the rendering is beginning.

Interval& valid

The validity interval for the update.
Default Implementation:
{ }

Reimplemented from SpecialFX.

{ }
virtual bool BuildMaps ( TimeValue  t,
RenderMapsContext rmc 
) [inline, virtual]
Remarks:
This method is called for the operator to do any work it needs to do prior to rendering. You may use this method to perform a subrender to sample the rendered output for histogramming or automatic exposure.
Parameters:
TimeValue t

The time at which the rendering is taking place.

RenderMapsContext& rmc

The context of the map rendering.
Returns:
True means this method succeeded. False means it didn't. This method should return false if it the sub-render fails or if it can't allocate memory or some other error occurs. If BuildMaps returns false, the render is aborted.
Default Implementation:
{ return true; }
        { return true; }
virtual void SubRenderSample ( float  energy[3] ) [inline, virtual]
virtual void ScaledToRGB ( float  energy[3] ) [pure virtual]
Remarks:
This method maps a scaled energy value into RGB. This version converts a color value. The converted color value is stored in energy.

This method assumes that Update() has been called to cache the various values needed by the tone operator.

Note: By using a float array to pass in color values, we can use the same routine to handle the various classes used to store color information, for example, Color, AColor and Point3.
Parameters:
float energy[3]

The input energy value to convert. The converted color value is stored here as well. The red, green and blue components are stored in that order in the array. The valid ranges are -infinity to +infinity, but the returned value is clipped by the renderer very quickly to [0,1]. The tone operator can do it's own clipping, but it isn't required.
virtual float ScaledToRGB ( float  energy ) [pure virtual]
Remarks:
This method maps a scaled energy value to monochrome. The converted monochrome value is returned. This method assumes that Update() has been called to cache the various values needed by the tone operator.
Parameters:
float energy

The input energy value to convert.
virtual float GetPhysicalUnit ( TimeValue  t,
Interval valid = Interval(0, 0) 
) const [pure virtual]
Remarks:
This method returns the physical value that is scaled to 1.
Parameters:
TimeValue t

The time at which to return the value.

Interval& valid = Interval(0,0)

The validity interval for the value.
virtual void SetPhysicalUnit ( float  value,
TimeValue  t 
) [pure virtual]
Remarks:
This method sets the physical value that is scale to 1. This is simply a programatic method to change the physical scaling of the tone operator. Valid values are (0,+infinity).
Parameters:
TimeValue t

The time at which to set the value.

Interval& valid = Interval(0,0)

The validity interval for the value.
virtual void ScalePhysical ( float  energy[3] ) const [pure virtual]
Remarks:
This method is used to scale a physical color value so it may be used in the renderer.

This method assumes that Update has been called to cache the various values needed by the tone operator.

Note: By using a float array to pass in color values, we can use the same routine to handle the various classes used to store color information, for example, Color, AColor and Point3.
Parameters:
float energy[3]

The input and output (converted) color value. The colors are stored as red=energy[0], green=energy[1], and blue=energy[2].
virtual float ScalePhysical ( float  energy ) const [pure virtual]
Remarks:
This method is used to scale a physical monochrome value so it may be used in the renderer.

This method assumes that Update has been called to cache the various values needed by the tone operator.
Parameters:
float energy

The input value to scale.
Returns:
The scaled output value is returned.
virtual void ScaleRGB ( float  color[3] ) const [pure virtual]
Remarks:
This method is called to scale RGB values (the inverse of ScalePhysical()).

This method assumes that Update has been called to cache the various values needed by the tone operator.
Parameters:
float color[3]

The input values to scale and storage for the output scaled values as well. The colors are stored as red=energy[0], green=energy[1], and blue=energy[2]. The output values are in the range 0-1.
virtual float ScaleRGB ( float  color ) const [pure virtual]
Remarks:
This method is called to scale a monochrome value (the inverse of ScalePhysical()).
Parameters:
float color

The input value to scale.
Returns:
The scaled output value is returned.
bool CanInvert ( ) [inline]
{
    return GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE) != NULL;
}
void RGBToScaled ( float  energy[3] ) [inline]
{
    ToneOperatorInvertable* p = static_cast<ToneOperatorInvertable*>(
        GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE));
        
    if (p != NULL)
        p->InverseMap(energy);
}
float RGBToScaled ( float  energy ) [inline]
{
    ToneOperatorInvertable* p = static_cast<ToneOperatorInvertable*>(
        GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE));
        
    return p == NULL ? energy : p->InverseMap(energy);
}

ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator
ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator ToneOperator