#include "simpleNoiseShaderOverride.h"
#include <maya/MViewport2Renderer.h>
#include <maya/MFragmentManager.h>
#include <maya/MTextureManager.h>
#include <maya/MShaderManager.h>
#include <maya/MRenderUtil.h>
#include <vector>
#include <assert.h>
namespace
{
const MString sFinalFragmentGraphName(
"simpleNoise");
const MString sNoiseLookupTextureName(
"simpleNoiseLookupTexture");
const std::vector<float>& GetMayaNoiseTable()
{
static std::vector<float> sNoiseData;
if (sNoiseData.empty())
{
sNoiseData.resize(dataSize);
for (unsigned int i=0; i<dataSize; i++)
{
}
}
return sNoiseData;
}
}
{
return new simpleNoiseShaderOverride(obj);
}
simpleNoiseShaderOverride::simpleNoiseShaderOverride(
const MObject& obj)
: MPxShadingNodeOverride(obj)
, fObject(obj)
, fNoiseTexture(NULL)
, fNoiseSamplerState(NULL)
, fResolvedNoiseMapName("")
, fResolvedNoiseSamplerName("")
{
}
simpleNoiseShaderOverride::~simpleNoiseShaderOverride()
{
if (renderer)
{
if (textureMgr)
{
fNoiseTexture = NULL;
}
}
fNoiseSamplerState = NULL;
}
MHWRender::DrawAPI simpleNoiseShaderOverride::supportedDrawAPIs() const
{
return
MHWRender::kOpenGL |
MHWRender::kDirectX11 |
MHWRender::kOpenGLCoreProfile;
}
MString simpleNoiseShaderOverride::fragmentName()
const
{
fResolvedNoiseMapName = "";
fResolvedNoiseSamplerName = "";
return sFinalFragmentGraphName;
}
void simpleNoiseShaderOverride::getCustomMappings(
{
"noiseLookupMap", "", false, true);
"noiseLookupMapSampler", "", false, true);
mappings.
append(textureSamplerMapping);
}
void simpleNoiseShaderOverride::updateShader(
{
if (fResolvedNoiseMapName.length() == 0)
{
if (mapping)
{
}
}
if (fResolvedNoiseSamplerName.length() == 0)
{
if (mapping)
{
}
}
if (fResolvedNoiseMapName.length() > 0 &&
fResolvedNoiseSamplerName.length() > 0)
{
if (!fNoiseSamplerState)
{
fNoiseSamplerState =
}
if (fNoiseSamplerState)
{
shader.
setParameter(fResolvedNoiseSamplerName, *fNoiseSamplerState);
}
if (!fNoiseTexture)
{
if (textureMgr)
{
fNoiseTexture =
if (!fNoiseTexture)
{
const std::vector<float>& noiseData = GetMayaNoiseTable();
desc.
fFormat = MHWRender::kR32_FLOAT;
sNoiseLookupTextureName,
desc,
(const void*)&(noiseData[0]),
false);
}
}
}
if (fNoiseTexture)
{
textureAssignment.
texture = fNoiseTexture;
shader.
setParameter(fResolvedNoiseMapName, textureAssignment);
}
}
}
MStatus simpleNoiseShaderOverride::registerFragments()
{
: NULL;
if (!fragmentMgr) return MS::kFailure;
if (fragmentMgr->
hasFragment(sFinalFragmentGraphName))
return MS::kSuccess;
const char* fragmentBody = NULL;
fragmentName = "simpleNoiseOutput";
fragmentBody =
"<fragment uiName=\"simpleNoiseOutput\" name=\"simpleNoiseOutput\" type=\"structure\" class=\"ShadeFragment\" version=\"1.0\"> \r\n"
" <description><![CDATA[Struct output for simple noise shader]]></description> \r\n"
" <properties> \r\n"
" <struct name=\"simpleNoiseOutput\" struct_name=\"simpleNoiseOutput\" /> \r\n"
" </properties> \r\n"
" <values> \r\n"
" </values> \r\n"
" <outputs> \r\n"
" <alias name=\"simpleNoiseOutput\" struct_name=\"simpleNoiseOutput\" /> \r\n"
" <float3 name=\"outColor\" /> \r\n"
" <float name=\"outAlpha\" /> \r\n"
" </outputs> \r\n"
" <implementation> \r\n"
" <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\"> \r\n"
" <function_name val=\"\" /> \r\n"
" <declaration name=\"simpleNoiseOutput\"><![CDATA[ \r\n"
"struct simpleNoiseOutput \r\n"
"{ \r\n"
" float3 outColor; \r\n"
" float outAlpha; \r\n"
"}; \r\n"
" ]]></declaration> \r\n"
" </implementation> \r\n"
" <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\"> \r\n"
" <function_name val=\"\" /> \r\n"
" <declaration name=\"simpleNoiseOutput\"><![CDATA[ \r\n"
"struct simpleNoiseOutput \r\n"
"{ \r\n"
" float3 outColor; \r\n"
" float outAlpha; \r\n"
"}; \r\n"
" ]]></declaration> \r\n"
" </implementation> \r\n"
" <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\"> \r\n"
" <function_name val=\"\" /> \r\n"
" <declaration name=\"simpleNoiseOutput\"><![CDATA[ \r\n"
"struct simpleNoiseOutput \r\n"
"{ \r\n"
" vec3 outColor; \r\n"
" float outAlpha; \r\n"
"}; \r\n"
" ]]></declaration> \r\n"
" </implementation> \r\n"
" </implementation> \r\n"
"</fragment> \r\n";
fragmentName = "simpleNoiseBase";
fragmentBody =
"<fragment uiName=\"simpleNoiseBase\" name=\"simpleNoiseBase\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\"> \r\n"
" <description><![CDATA[Computes simple 2D procedural noise]]></description> \r\n"
" <properties> \r\n"
" <float2 name=\"uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" /> \r\n"
" <texture3 name=\"noiseLookupMap\" /> \r\n"
" <sampler name=\"noiseLookupMapSampler\" /> \r\n"
" <float name=\"amplitude\" /> \r\n"
" <float name=\"ratio\" /> \r\n"
" <int name=\"depthMax\" /> \r\n"
" <float name=\"frequency\" /> \r\n"
" <float name=\"frequencyRatio\" /> \r\n"
" <float name=\"time\" /> \r\n"
" <int name=\"numWaves\" /> \r\n"
" </properties> \r\n"
" <values> \r\n"
" <float name=\"amplitude\" value=\"1.0\" /> \r\n"
" <float name=\"ratio\" value=\"0.707000\" /> \r\n"
" <int name=\"depthMax\" value=\"3\" /> \r\n"
" <float name=\"frequency\" value=\"8.0\" /> \r\n"
" <float name=\"frequencyRatio\" value=\"2.0\" /> \r\n"
" <float name=\"time\" value=\"0.0\" /> \r\n"
" <int name=\"numWaves\" value=\"5\" /> \r\n"
" </values> \r\n"
" <outputs> \r\n"
" <struct name=\"simpleNoiseBase\" struct_name=\"simpleNoiseOutput\" /> \r\n"
" </outputs> \r\n"
" <implementation> \r\n"
" <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\"> \r\n"
" <function_name val=\"simpleNoise\" /> \r\n"
" <source><![CDATA[ \r\n"
"float simpleNoise_RawNoiseLookup( \r\n"
" int index, \r\n"
" texture3D noiseLookupMap, \r\n"
" sampler3D noiseLookupMapSampler) \r\n"
"{ \r\n"
" int3 index3; \r\n"
" index3.x = index; \r\n"
" index3.y = (index>> 5); \r\n"
" index3.z = (index>> 10); \r\n"
" index3 &= 31; \r\n"
" float3 uvw = float3(index3) / 32.0f; \r\n"
" return (tex3D(noiseLookupMapSampler, uvw).r * 2.0f) - 1.0f; \r\n"
"} \r\n"
"simpleNoiseOutput simpleNoise( \r\n"
" float2 uv, \r\n"
" texture3D noiseLookupMap, \r\n"
" sampler3D noiseLookupMapSampler, \r\n"
" float amplitude, \r\n"
" float ratio, \r\n"
" int depthMax, \r\n"
" float frequency, \r\n"
" float frequencyRatio, \r\n"
" float time, \r\n"
" int numWaves) \r\n"
"{ \r\n"
" const float M_PI = 3.1415926535897f; \r\n"
" const float M_2PI = 2.0f*M_PI; \r\n"
" simpleNoiseOutput finalResult; \r\n"
" float timeRatio = sqrt(frequencyRatio); \r\n"
" uv *= frequency; \r\n"
" float cosine = 0.0f; \r\n"
" float noise = 0.0f; \r\n"
" int depthId = 0; \r\n"
" int waveId = 0; \r\n"
" int seedOffset = 0; \r\n"
" while (depthId<depthMax && waveId<numWaves) { \r\n"
" int step = depthId; \r\n"
" int seed = 50*step; \r\n"
" float2 dir = float2( \r\n"
" simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMap, noiseLookupMapSampler), \r\n"
" simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMap, noiseLookupMapSampler)); \r\n"
" float norm = length(dir); \r\n"
" if (norm <= 0.0f) continue; \r\n"
" dir /= norm; \r\n"
" noise += cos(dir.x*uv.x*M_2PI + dir.y*uv.y*M_2PI + M_PI*simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMap, noiseLookupMapSampler) + time*M_PI); \r\n"
" ++waveId; \r\n"
" if (waveId < numWaves) continue; \r\n"
" noise /= float(numWaves); \r\n"
" uv *= frequencyRatio; \r\n"
" time *= timeRatio; \r\n"
" cosine += amplitude * noise; \r\n"
" amplitude *= ratio; \r\n"
" noise = 0.0f; \r\n"
" waveId = 0; \r\n"
" seedOffset = 0; \r\n"
" ++depthId; \r\n"
" } \r\n"
" cosine = 0.5f*cosine + 0.5f; \r\n"
" float noiseVal = (cosine> 1.0f) ? 1.0f : cosine; \r\n"
" finalResult.outColor = float3(noiseVal, noiseVal, noiseVal); \r\n"
" finalResult.outAlpha = noiseVal; \r\n"
" return finalResult; \r\n"
"} \r\n"
" ]]></source> \r\n"
" </implementation> \r\n"
" <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\"> \r\n"
" <function_name val=\"simpleNoise\" /> \r\n"
" <source><![CDATA[ \r\n"
"float simpleNoise_RawNoiseLookup( \r\n"
" int index, \r\n"
" Texture3D noiseLookupMap, \r\n"
" sampler noiseLookupMapSampler) \r\n"
"{ \r\n"
" int3 index3; \r\n"
" index3.x = index; \r\n"
" index3.y = (index>> 5); \r\n"
" index3.z = (index>> 10); \r\n"
" index3 &= 31; \r\n"
" float3 uvw = float3(index3) / 32.0f; \r\n"
" return (noiseLookupMap.SampleLevel(noiseLookupMapSampler, uvw, 0).r * 2.0f) - 1.0f; \r\n"
"} \r\n"
"simpleNoiseOutput simpleNoise( \r\n"
" float2 uv, \r\n"
" Texture3D noiseLookupMap, \r\n"
" sampler noiseLookupMapSampler, \r\n"
" float amplitude, \r\n"
" float ratio, \r\n"
" int depthMax, \r\n"
" float frequency, \r\n"
" float frequencyRatio, \r\n"
" float time, \r\n"
" int numWaves) \r\n"
"{ \r\n"
" const float M_PI = 3.1415926535897f; \r\n"
" const float M_2PI = 2.0f*M_PI; \r\n"
" simpleNoiseOutput finalResult; \r\n"
" float timeRatio = sqrt(frequencyRatio); \r\n"
" uv *= frequency; \r\n"
" float cosine = 0.0f; \r\n"
" float noise = 0.0f; \r\n"
" int depthId = 0; \r\n"
" int waveId = 0; \r\n"
" int seedOffset = 0; \r\n"
" while (depthId<depthMax && waveId<numWaves) { \r\n"
" int step = depthId; \r\n"
" int seed = 50*step; \r\n"
" float2 dir = float2( \r\n"
" simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMap, noiseLookupMapSampler), \r\n"
" simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMap, noiseLookupMapSampler)); \r\n"
" float norm = length(dir); \r\n"
" if (norm <= 0.0f) continue; \r\n"
" dir /= norm; \r\n"
" noise += cos(dir.x*uv.x*M_2PI + dir.y*uv.y*M_2PI + M_PI*simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMap, noiseLookupMapSampler) + time*M_PI); \r\n"
" ++waveId; \r\n"
" if (waveId < numWaves) continue; \r\n"
" noise /= float(numWaves); \r\n"
" uv *= frequencyRatio; \r\n"
" time *= timeRatio; \r\n"
" cosine += amplitude * noise; \r\n"
" amplitude *= ratio; \r\n"
" noise = 0.0f; \r\n"
" waveId = 0; \r\n"
" seedOffset = 0; \r\n"
" ++depthId; \r\n"
" } \r\n"
" cosine = 0.5f*cosine + 0.5f; \r\n"
" float noiseVal = (cosine> 1.0f) ? 1.0f : cosine; \r\n"
" finalResult.outColor = float3(noiseVal, noiseVal, noiseVal); \r\n"
" finalResult.outAlpha = noiseVal; \r\n"
" return finalResult; \r\n"
"} \r\n"
" ]]></source> \r\n"
" </implementation> \r\n"
" <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\"> \r\n"
" <function_name val=\"simpleNoise\" /> \r\n"
" <source><![CDATA[ \r\n"
"float simpleNoise_RawNoiseLookup( \r\n"
" int index, \r\n"
" sampler3D noiseLookupMapSampler) \r\n"
"{ \r\n"
" ivec3 index3; \r\n"
" index3.x = index; \r\n"
" index3.y = (index >> 5); \r\n"
" index3.z = (index >> 10); \r\n"
" index3 &= 31; \r\n"
" vec3 uvw = vec3(index3) / 32.0f; \r\n"
" return (texture(noiseLookupMapSampler, uvw).r * 2.0f) - 1.0f; \r\n"
"} \r\n"
"simpleNoiseOutput simpleNoise( \r\n"
" vec2 uv, \r\n"
" sampler3D noiseLookupMapSampler, \r\n"
" float amplitude, \r\n"
" float ratio, \r\n"
" int depthMax, \r\n"
" float frequency, \r\n"
" float frequencyRatio, \r\n"
" float time, \r\n"
" int numWaves) \r\n"
"{ \r\n"
" const float M_PI = 3.1415926535897f; \r\n"
" const float M_2PI = 2.0f*M_PI; \r\n"
" simpleNoiseOutput finalResult; \r\n"
" float timeRatio = sqrt(frequencyRatio); \r\n"
" uv *= frequency; \r\n"
" float cosine = 0.0f; \r\n"
" float noise = 0.0f; \r\n"
" int depthId = 0; \r\n"
" int waveId = 0; \r\n"
" int seedOffset = 0; \r\n"
" while (depthId<depthMax && waveId<numWaves) { \r\n"
" int step = depthId; \r\n"
" int seed = 50*step; \r\n"
" vec2 dir = vec2( \r\n"
" simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMapSampler), \r\n"
" simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMapSampler)); \r\n"
" float norm = length(dir); \r\n"
" if (norm <= 0.0f) continue; \r\n"
" dir /= norm; \r\n"
" noise += cos(dir.x*uv.x*M_2PI + dir.y*uv.y*M_2PI + M_PI*simpleNoise_RawNoiseLookup(seed + seedOffset++, noiseLookupMapSampler) + time*M_PI); \r\n"
" ++waveId; \r\n"
" if (waveId < numWaves) continue; \r\n"
" noise /= float(numWaves); \r\n"
" uv *= frequencyRatio; \r\n"
" time *= timeRatio; \r\n"
" cosine += amplitude * noise; \r\n"
" amplitude *= ratio; \r\n"
" noise = 0.0f; \r\n"
" waveId = 0; \r\n"
" seedOffset = 0; \r\n"
" ++depthId; \r\n"
" } \r\n"
" cosine = 0.5f*cosine + 0.5f; \r\n"
" float noiseVal = (cosine > 1.0f) ? 1.0f : cosine; \r\n"
" finalResult.outColor = vec3(noiseVal, noiseVal, noiseVal); \r\n"
" finalResult.outAlpha = noiseVal; \r\n"
" return finalResult; \r\n"
"} \r\n"
" ]]></source> \r\n"
" </implementation> \r\n"
" </implementation> \r\n"
"</fragment> \r\n";
fragmentName = sFinalFragmentGraphName;
fragmentBody =
"<fragment_graph name=\"simpleNoise\" ref=\"simpleNoise\" class=\"FragmentGraph\" version=\"1.0\"> \r\n"
" <fragments> \r\n"
" <fragment_ref name=\"simpleNoiseBase\" ref=\"simpleNoiseBase\" /> \r\n"
" <fragment_ref name=\"simpleNoiseOutput\" ref=\"simpleNoiseOutput\" /> \r\n"
" </fragments> \r\n"
" <connections> \r\n"
" <connect from=\"simpleNoiseBase.simpleNoiseBase\" to=\"simpleNoiseOutput.simpleNoiseOutput\" name=\"simpleNoiseOutput\" /> \r\n"
" </connections> \r\n"
" <properties> \r\n"
" <float2 name=\"uvCoord\" ref=\"simpleNoiseBase.uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" /> \r\n"
" <texture3 name=\"noiseLookupMap\" ref=\"simpleNoiseBase.noiseLookupMap\" /> \r\n"
" <sampler name=\"noiseLookupMapSampler\" ref=\"simpleNoiseBase.noiseLookupMapSampler\" /> \r\n"
" <float name=\"amplitude\" ref=\"simpleNoiseBase.amplitude\" /> \r\n"
" <float name=\"ratio\" ref=\"simpleNoiseBase.ratio\" /> \r\n"
" <int name=\"depthMax\" ref=\"simpleNoiseBase.depthMax\" /> \r\n"
" <float name=\"frequency\" ref=\"simpleNoiseBase.frequency\" /> \r\n"
" <float name=\"frequencyRatio\" ref=\"simpleNoiseBase.frequencyRatio\" /> \r\n"
" <float name=\"time\" ref=\"simpleNoiseBase.time\" /> \r\n"
" <int name=\"numWaves\" ref=\"simpleNoiseBase.numWaves\" /> \r\n"
" </properties> \r\n"
" <values> \r\n"
" <float name=\"amplitude\" value=\"1.0\" /> \r\n"
" <float name=\"ratio\" value=\"0.707000\" /> \r\n"
" <int name=\"depthMax\" value=\"3\" /> \r\n"
" <float name=\"frequency\" value=\"8.0\" /> \r\n"
" <float name=\"frequencyRatio\" value=\"2.0\" /> \r\n"
" <float name=\"time\" value=\"0.0\" /> \r\n"
" <int name=\"numWaves\" value=\"5\" /> \r\n"
" </values> \r\n"
" <outputs> \r\n"
" <struct name=\"simpleNoiseOutput\" ref=\"simpleNoiseOutput.simpleNoiseOutput\" /> \r\n"
" </outputs> \r\n"
"</fragment_graph> \r\n";
return MS::kSuccess;
}
MStatus simpleNoiseShaderOverride::deregisterFragments()
{
: NULL;
if (!fragmentMgr) return MS::kFailure;
if (!fragmentMgr->
removeFragment(
"simpleNoiseOutput"))
return MS::kFailure;
if (!fragmentMgr->
removeFragment(
"simpleNoiseBase"))
return MS::kFailure;
if (!fragmentMgr->
removeFragment(sFinalFragmentGraphName))
return MS::kFailure;
return MS::kSuccess;
}