#include <maya/MPxNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MIOStream.h>
#include <maya/MDrawRegistry.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnLightDataAttribute.h>
#include <algorithm>
#include "onbShaderOverride.h"
{
public:
static void* creator();
static MString drawDbClassification;
OnbShader();
~OnbShader() override;
SchedulingType
schedulingType()
const override {
return SchedulingType::kParallel; }
private:
static MObject aLightShadowFraction;
static MObject aPreShadowIntensity;
};
MString OnbShader::nodeName(
"onbShader");
MString OnbShader::drawDbClassification(
"drawdb/shader/surface/onbShader");
MString OnbShader::classification(
"shader/surface:" + drawDbClassification);
MObject OnbShader::aOutTransparency;
MObject OnbShader::aSpecularRollOff;
MObject OnbShader::aLightDirection;
MObject OnbShader::aLightIntensity;
MObject OnbShader::aLightShadowFraction;
MObject OnbShader::aPreShadowIntensity;
MObject OnbShader::aLightBlindData;
#define MAKE_INPUT(attr) \
CHECK_MSTATUS(attr.setKeyable(true)); \
CHECK_MSTATUS(attr.setStorable(true)); \
CHECK_MSTATUS(attr.setReadable(true)); \
CHECK_MSTATUS(attr.setWritable(true));
#define MAKE_OUTPUT(attr) \
CHECK_MSTATUS(attr.setKeyable(false)); \
CHECK_MSTATUS(attr.setStorable(false)); \
CHECK_MSTATUS(attr.setReadable(true)); \
CHECK_MSTATUS(attr.setWritable(false));
OnbShader::OnbShader()
{
}
OnbShader::~OnbShader()
{
}
void* OnbShader::creator()
{
return new OnbShader();
}
{
MObject outcR = nAttr.
create(
"outColorR",
"ocr", MFnNumericData::kFloat, 0.0);
MObject outcG = nAttr.
create(
"outColorG",
"ocg", MFnNumericData::kFloat, 0.0);
MObject outcB = nAttr.
create(
"outColorB",
"ocb", MFnNumericData::kFloat, 0.0);
aOutColor = nAttr.
create(
"outColor",
"oc", outcR, outcG, outcB);
MAKE_OUTPUT(nAttr);
MObject outtR = nAttr.
create(
"outTransparencyR",
"otr", MFnNumericData::kFloat, 0.0);
MObject outtG = nAttr.
create(
"outTransparencyG",
"otg", MFnNumericData::kFloat, 0.0);
MObject outtB = nAttr.
create(
"outTransparencyB",
"otb", MFnNumericData::kFloat, 0.0);
aOutTransparency = nAttr.
create(
"outTransparency",
"ot", outtR, outtG, outtB);
MAKE_OUTPUT(nAttr);
MObject cR = nAttr.
create(
"colorR",
"cr", MFnNumericData::kFloat, 0.5);
MObject cG = nAttr.
create(
"colorG",
"cg", MFnNumericData::kFloat, 0.5);
MObject cB = nAttr.
create(
"colorB",
"cb", MFnNumericData::kFloat, 0.5);
aColor = nAttr.
create(
"color",
"c", cR, cG, cB);
MAKE_INPUT(nAttr);
aRoughness = nAttr.
create(
"roughness",
"r", MFnNumericData::kFloat);
MAKE_INPUT(nAttr);
MObject tR = nAttr.
create(
"transparencyR",
"itr", MFnNumericData::kFloat, 0.0);
MObject tG = nAttr.
create(
"transparencyG",
"itg", MFnNumericData::kFloat, 0.0);
MObject tB = nAttr.
create(
"transparencyB",
"itb", MFnNumericData::kFloat, 0.0);
aTransparency = nAttr.
create(
"transparency",
"it", tR, tG, tB);
MAKE_INPUT(nAttr);
MObject aR = nAttr.
create(
"ambientColorR",
"acr", MFnNumericData::kFloat, 0.0);
MObject aG = nAttr.
create(
"ambientColorG",
"acg", MFnNumericData::kFloat, 0.0);
MObject aB = nAttr.
create(
"ambientColorB",
"acb", MFnNumericData::kFloat, 0.0);
aAmbientColor = nAttr.
create(
"ambientColor",
"ambc", aR, aG, aB);
MAKE_INPUT(nAttr);
MObject iR = nAttr.
create(
"incandescenceR",
"ir", MFnNumericData::kFloat, 0.0);
MObject iG = nAttr.
create(
"incandescenceG",
"ig", MFnNumericData::kFloat, 0.0);
MObject iB = nAttr.
create(
"incandescenceB",
"ib", MFnNumericData::kFloat, 0.0);
aIncandescence = nAttr.
create(
"incandescence",
"ic", iR, iG, iB);
MAKE_INPUT(nAttr);
MObject sR = nAttr.
create(
"specularColorR",
"sr", MFnNumericData::kFloat, 1.0);
MObject sG = nAttr.
create(
"specularColorG",
"sg", MFnNumericData::kFloat, 1.0);
MObject sB = nAttr.
create(
"specularColorB",
"sb", MFnNumericData::kFloat, 1.0);
aSpecularColor = nAttr.
create(
"specularColor",
"sc", sR, sG, sB);
MAKE_INPUT(nAttr);
aEccentricity = nAttr.
create(
"eccentricity",
"ecc", MFnNumericData::kFloat);
MAKE_INPUT(nAttr);
aSpecularRollOff = nAttr.
create(
"specularRollOff",
"sro", MFnNumericData::kFloat);
MAKE_INPUT(nAttr);
aNormalCamera = nAttr.
createPoint(
"normalCamera",
"n");
MAKE_INPUT(nAttr);
aRayDirection = nAttr.
createPoint(
"rayDirection",
"rd");
MAKE_INPUT(nAttr);
aLightDirection = nAttr.
createPoint(
"lightDirection",
"ld");
aLightIntensity = nAttr.
createColor(
"lightIntensity",
"li");
aLightAmbient = nAttr.
create(
"lightAmbient",
"la", MFnNumericData::kBoolean);
aLightDiffuse = nAttr.
create(
"lightDiffuse",
"ldf", MFnNumericData::kBoolean);
aLightSpecular = nAttr.
create(
"lightSpecular",
"ls", MFnNumericData::kBoolean);
aLightShadowFraction = nAttr.
create(
"lightShadowFraction",
"lsf", MFnNumericData::kFloat);
aPreShadowIntensity = nAttr.
create(
"preShadowIntensity",
"psi", MFnNumericData::kFloat);
aLightBlindData = nAttr.
createAddr(
"lightBlindData",
"lbld");
aLightData = lAttr.
create(
"lightDataArray",
"ltd",
aLightDirection,
aLightIntensity,
aLightAmbient,
aLightDiffuse,
aLightSpecular,
aLightShadowFraction,
aPreShadowIntensity,
aLightBlindData);
CHECK_MSTATUS(lAttr.
setDefault(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
true,
true,
false, 0.0f, 1.0f, NULL));
CHECK_MSTATUS(attributeAffects(aTransparency, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aAmbientColor, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aIncandescence, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aSpecularColor, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aEccentricity, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aNormalCamera, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aRayDirection, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aSpecularRollOff, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aLightDirection, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aLightIntensity, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aLightAmbient, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aLightDiffuse, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aLightSpecular, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aLightShadowFraction, aOutColor));
CHECK_MSTATUS(attributeAffects(aLightShadowFraction, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aPreShadowIntensity, aOutTransparency));
CHECK_MSTATUS(attributeAffects(aLightBlindData, aOutTransparency));
return MS::kSuccess;
}
{
if (plug != aOutColor && plug.
parent() != aOutColor &&
plug != aOutTransparency && plug.
parent() != aOutTransparency)
{
return MS::kUnknownParameter;
}
const float NV = viewDirection*surfaceNormal;
const float acosNV = acosf(NV);
const float roughnessSq = roughness*roughness;
const float A = 1.0f - 0.5f*(roughnessSq/(roughnessSq + 0.57f));
const float B = 0.45f*(roughnessSq/(roughnessSq + 0.09f));
for (int count=1; count<=numLights; count++)
{
{
const float NL = lightDirection*surfaceNormal;
const float acosNL = acosf(NL);
const float alpha = std::max(acosNV, acosNL);
const float beta = std::min(acosNV, acosNL);
const float gamma =
(viewDirection - (surfaceNormal*NV)) *
(lightDirection - (surfaceNormal*NL));
const float C = sinf(alpha)*tanf(beta);
const float factor =
std::max(0.0f, NL)*(A + B*std::max(0.0f, gamma)*C);
resultColor += lightIntensity*factor;
}
if (count < numLights)
{
status = lightData.
next();
}
}
resultColor[0] = resultColor[0]*surfaceColor[0];
resultColor[1] = resultColor[1]*surfaceColor[1];
resultColor[2] = resultColor[2]*surfaceColor[2];
if (plug == aOutColor || plug.
parent() == aOutColor)
{
outColor = resultColor;
}
if (plug == aOutTransparency || plug.
parent() == aOutTransparency)
{
outTrans = transparency;
}
return MS::kSuccess;
}
static const MString sRegistrantId(
"onbShaderPlugin");
{
MFnPlugin plugin(obj, PLUGIN_COMPANY,
"1.0",
"Any");
OnbShader::nodeName,
OnbShader::id,
OnbShader::creator,
OnbShader::initialize,
MPxNode::kDependNode,
&OnbShader::classification));
OnbShader::drawDbClassification,
sRegistrantId,
onbShaderOverride::creator));
return MS::kSuccess;
}
{
OnbShader::drawDbClassification,
sRegistrantId));
return MS::kSuccess;
}