#include <maya/MPxNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MIOStream.h>
#include <maya/MDrawRegistry.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MRenderUtil.h>
#include "simpleNoiseShaderOverride.h"
class SimpleNoiseShader :
public MPxNode
{
public:
static void* creator();
static const MString drawDbClassification;
static const MString classification;
SimpleNoiseShader();
~SimpleNoiseShader() override;
SchedulingType
schedulingType()
const override {
return SchedulingType::kParallel; }
private:
};
const MTypeId SimpleNoiseShader::id(0x00080FFE);
const MString SimpleNoiseShader::nodeName(
"simpleNoise");
const MString SimpleNoiseShader::drawDbClassification(
"drawdb/shader/texture/2d/" + SimpleNoiseShader::nodeName);
const MString SimpleNoiseShader::classification(
"texture/2d:" + drawDbClassification);
MObject SimpleNoiseShader::aOutColor;
MObject SimpleNoiseShader::aOutAlpha;
MObject SimpleNoiseShader::aUVCoord;
MObject SimpleNoiseShader::aFilterSize;
MObject SimpleNoiseShader::aAmplitude;
MObject SimpleNoiseShader::aDepthMax;
MObject SimpleNoiseShader::aFrequency;
MObject SimpleNoiseShader::aFrequencyRatio;
MObject SimpleNoiseShader::aNumWaves;
#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));
SimpleNoiseShader::SimpleNoiseShader()
{
}
SimpleNoiseShader::~SimpleNoiseShader()
{
}
void* SimpleNoiseShader::creator()
{
return new SimpleNoiseShader();
}
MStatus SimpleNoiseShader::initialize()
{
aOutColor = nAttr.
create(
"outColor",
"oc", outcR, outcG, outcB);
MAKE_OUTPUT(nAttr);
MAKE_OUTPUT(nAttr);
aUVCoord = nAttr.
create(
"uvCoord",
"uv", child1, child2);
MAKE_INPUT(nAttr);
aFilterSize = nAttr.
create(
"uvFilterSize",
"fs", child1, child2);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
return MS::kSuccess;
}
{
if (plug != aOutColor && plug.
parent() != aOutColor && plug != aOutAlpha)
{
return MS::kUnknownParameter;
}
float resultAlpha = 1.0f;
static const float fM_PI = (float)M_PI;
static const float M_2PI = 2.0f*fM_PI;
const float timeRatio = sqrt(frequencyRatio);
float uvX = uv[0] * frequency;
float uvY = uv[1] * frequency;
float cosine = 0.0f;
float noise = 0.0f;
unsigned int depthId = 0;
unsigned int waveId = 0;
unsigned int seedOffset = 0;
while (depthId<depthMax && waveId<numWaves)
{
const unsigned int step = depthId;
const unsigned int seed = 50*step;
const float norm = sqrtf(dirX*dirX + dirY*dirY);
if (norm <= 0.0f) continue;
dirX /= norm;
dirY /= norm;
noise += cosf(
dirX*uvX*M_2PI +
dirY*uvY*M_2PI +
time*fM_PI);
++waveId;
if (waveId < numWaves) continue;
noise /= float(numWaves);
uvX *= frequencyRatio;
uvY *= frequencyRatio;
time *= timeRatio;
cosine += amplitude * noise;
amplitude *= ratio;
noise = 0.0f;
waveId = 0;
seedOffset = 0;
++depthId;
}
cosine = 0.5f*cosine + 0.5f;
const float noiseVal = (cosine > 1.0f) ? 1.0f : cosine;
resultColor[0] = resultColor[1] = resultColor[2] = noiseVal;
resultAlpha = noiseVal;
if (plug == aOutColor || plug.
parent() == aOutColor)
{
outColor = resultColor;
}
if (plug == aOutAlpha)
{
float& outAlpha = outAlphaHandle.
asFloat();
outAlpha = resultAlpha;
}
return MS::kSuccess;
}
static const MString sRegistrantId(
"simpleNoiseShaderPlugin");
{
MFnPlugin plugin(obj, PLUGIN_COMPANY,
"1.0",
"Any");
SimpleNoiseShader::nodeName,
SimpleNoiseShader::id,
SimpleNoiseShader::creator,
SimpleNoiseShader::initialize,
&SimpleNoiseShader::classification));
SimpleNoiseShader::drawDbClassification,
sRegistrantId,
simpleNoiseShaderOverride::creator));
return MS::kSuccess;
}
{
SimpleNoiseShader::drawDbClassification,
sRegistrantId));
return MS::kSuccess;
}