class ISpecularCompositeShader
: public BaseInterface
- Description:
- This class is only available in release 5 or
later.
This class is only used to communicate some information between the
3ds Max Standard Material and the Shaders for the 3ds Max
Standard Material. The
information that the Shaders require that wasn't supplied previous
is the RenderGlobalContext. This
would be used by 3rd parties who want to write shaders for the 3ds
Max standard material. This is only required if the shader performs
operations that are not valid for arbitrary light values. For
example: Using the default values, the Physical Sun has light
multiplier values that are around 60.
Several standard 3ds Max shaders, like the Aniso and ONB shaders,
composite specular highlights over the diffuse light, and the
calculation looks something like:
color = diffuse * (1 - specular) + specular;
This works fine as long as specular is between 0 and 1. If specular
goes above 1, you get all kinds of unusual artifacts. This
calculation is done this way to prevent color clipping because of
bright specular highlights. With lighting values at 60, the
specular is frequently greater than 1.With an exposure control, the
exposure control manages the color clipping and we can simply add
the diffuse and specular components.
This interface gives the shader a chance to investigate the render
parameters and decide how the lighting is to be combined.
This is usually done by using multiple inheritances and deriving
the Shader
Implementation from Shader and
ISpecularCompositeShader.
The Shader needs to
override GetInterface(Interface_ID
id) and return the address of the ISpecularCompositShader
interface and GetRequirements also needs to be overriden to return
MTLREQ_PREPRO as one of the shader requirements.
Then the shader needs to implement ChooseSpecularMethod. The
typical implementation is:
void CombineComponentsCompShader::ChooseSpecularMethod(TimeValue t,
RenderGlobalContext* rgc)
{
useComposite = true;
if (rgc == NULL) {
ToneOperatorInterface* tint =
static_cast<ToneOperatorInterface*>(
GetCOREInterface(TONE_OPERATOR_INTERFACE));
if (tint != NULL) {
ToneOperator* top = tint->GetToneOperator();
if (top != NULL && top->Active(t))
useComposite = false;
}
} else {
ToneOperator* top = rgc->pToneOp;
if (top != NULL && top->Active(t))
useComposite = false;
}
}