Shading node override

Shading node override

Anonymous
Not applicable
2,336 Views
8 Replies
Message 1 of 9

Shading node override

Anonymous
Not applicable

Hi,

I am currently working on overriding the Shading node and I am using the fileTexture example as a reference. The sample plugin works as expected. However, when I make some changes to the fragments defined in the FileNodeOverride class, I get some very unexpected behavior.

I have attached the modified file for reference (hmm, can't seem to attach cpp files, please see snippets below).

As you can see, I made some changes to the shaders and force reload them (by unloading them and loading them again). Despite those changes (i.e. result.outColor being commented out), the plugin output works! It's not black or an undefined color but the correct texture color.

 

Here is the relevant portion of the shader for reference (I pasted GLSL portion here, but the same changes have been made for HLSL and CGFX, even though my current renderer in Maya is OpenGL):

 

Snippet

		"		<source><![CDATA["
		"fileTexturePluginFragmentOutput fileTexturePluginFragment(vec2 uv, sampler2D mapSampler) \n"
		"{ \n"
		"	fileTexturePluginFragmentOutput result; \n"
		"	uv -= floor(uv); \n"
		"	uv.y = 1.0f - uv.y; \n"
		"	vec4 color = texture(mapSampler, uv); \n"
		"	// result.outColor = vec3(1, 0, 0); // color.rgb; \n" // <------ !!!
		"	result.outAlpha = color.a; \n"
		"	return result; \n"
		"} \n]]>"
		"		</source>"



I even went as far as to introduce syntax errors in the fragments (missing semicolons) and not only did I not get any errors, the plugin worked as if I made no changes whatsoever!

 

Perhaps the shaders were loaded once and then were cached in the ShaderMgr? I made sure that they are removed and loaded again:

 

Snippet

		if (fragmentMgr)
		{
			// Add fragments if needed
			if (fragmentMgr->hasFragment(sFragmentName) == true)
			{ fragmentMgr->removeFragment(sFragmentName); }
 
			if (fragmentMgr->hasFragment(sFragmentOutputName) == true)
			{ fragmentMgr->removeFragment(sFragmentOutputName); }
 
			if (fragmentMgr->hasFragment(sFragmentGraphName) == true)
			{ fragmentMgr->removeFragment(sFragmentGraphName); }
 
			bool fragAdded = (sFragmentName == fragmentMgr->addShadeFragmentFromBuffer(sFragmentBody, false));
			bool structAdded = (sFragmentOutputName == fragmentMgr->addShadeFragmentFromBuffer(sFragmentOutputBody, false));
			bool graphAdded = (sFragmentGraphName == fragmentMgr->addFragmentGraphFromBuffer(sFragmentGraphBody));
 
			// If we have them all, use the final graph for the override
			if (fragAdded && structAdded && graphAdded)
			{
				fFragmentName = sFragmentGraphName;
			}
		}

 

Now, if I remove the lines that add the fragment from buffer, i.e. the shaders are no longer being loaded, then I get the expected behavior of the node not outputting the color of the texture in its output node.


I would be grateful if someone can demistify this for me.

0 Likes
Accepted solutions (1)
2,337 Views
8 Replies
Replies (8)
Message 2 of 9

Anonymous
Not applicable

It turns out that if I restart Maya and load the plugin, the new fragment changes go through. Making some headway, however I would like to know why fragmentMgr->removeFragment(fragmentName) doesn't remove the fragment from the cache? Restarting Maya every time I modify the fragment slightly is not an option especially considering I'll be loading the fragments from an XML file and would like it to reload the fragments through a custom command.

 

 

0 Likes
Message 3 of 9

cheng_xi_li
Autodesk Support
Autodesk Support
Accepted solution

Hi,

 

Could you try to call

MShaderManager::clearEffectCache after calling removeFragment? I've tried to add removeFragment in fileTexture sample when it unloads.

 

MStatus uninitializePlugin(MObject obj)
{
	MFnPlugin plugin(obj);
		

	CHECK_MSTATUS(plugin.deregisterNode(FileNode::id));

	CHECK_MSTATUS(
		MHWRender::MDrawRegistry::deregisterShadingNodeOverrideCreator(
			"drawdb/shader/texture/2d/fileTexture",
			sRegistrantId));
	MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();
	if (theRenderer)
	{
		MHWRender::MFragmentManager* fragmentMgr =
			theRenderer->getFragmentManager();
		auto shaderMgr = theRenderer->getShaderManager();

		if (fragmentMgr)
		{
			static const MString sFragmentOutputName("fileTexturePluginFragmentOutput");
			static const MString sFragmentName("fileTexturePluginFragment");
			static const MString sFragmentGraphName("fileTexturePluginGraph");

			bool fragAdded = fragmentMgr->hasFragment(sFragmentName);
			bool structAdded = fragmentMgr->hasFragment(sFragmentOutputName);
			bool graphAdded = fragmentMgr->hasFragment(sFragmentGraphName);

			
			if (fragAdded)
			{
				fragmentMgr->removeFragment(sFragmentName);
				MGlobal::displayInfo(MString("removeFragment:") + sFragmentName);
			}
			if (structAdded)
			{
				fragmentMgr->removeFragment(sFragmentOutputName);
				MGlobal::displayInfo(MString("removeFragment:") + sFragmentOutputName);

			}
			if (graphAdded)
			{
				fragmentMgr->removeFragment(sFragmentGraphName);
				MGlobal::displayInfo(MString("removeFragment:") + sFragmentGraphName);
			}
		}
		if(shaderMgr)
			shaderMgr->clearEffectCache();
	}

   return MS::kSuccess;
}

It works fine on My Computer.

 

Yours,

Li

0 Likes
Message 4 of 9

Anonymous
Not applicable

Thank you. Clearing the effects cache was the missing piece.

0 Likes
Message 5 of 9

Anonymous
Not applicable

Hi 

I am trying to change the input fragment in UpdateDG call. I have 2 shader instances one for non-textured mode and other for the textured mode.

clearEffectCache() working for textured mode i.e. on adding new fragment as input fragment on textured shader instance. But not working in case of non-textured shader instance as the newly added fragment is not effective.

 

Also, note I am releasing shader instances before adding new input fragments. And removing fragment from fragment manager did not help.

 

Thanks

 

 

0 Likes
Message 6 of 9

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

Can you send me a sample for reproducing the issue? I'll check it next Monday.

 

Yours,

Li

0 Likes
Message 7 of 9

Anonymous
Not applicable

Hi Cheng Xi Li,

Thank you for the reply.

Please find the sample attached.

I have used existing vp2 blinn shader from sample and added code to it. For workflow refer .gif  file

 The cpp code is as below:

#include <maya/MIOStream.h>
#include <math.h>
#include <cstdlib>

//#include <maya/MGlobal.h>
#include <maya/MString.h>
#include <maya/MPlug.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnDependencyNode.h>
//#include <maya/MUserData.h>

//#include <maya/MHardwareRenderer.h>

// Includes for swatch rendering
#include <maya/MHWShaderSwatchGenerator.h>
#include <maya/MImage.h>
#include <maya/MRenderUtilities.h>

#include <maya/MMatrix.h>

// Viewport 2.0 includes
#include <maya/MDrawRegistry.h>
#include <maya/MPxShaderOverride.h>
#include <maya/MDrawContext.h>
#include <maya/MStateManager.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MShaderManager.h>

//include for adding fragment
#include <maya/MFragmentManager.h>

#undef ENABLE_TRACE_API_CALLS
//#define ENABLE_TRACE_API_CALLS 1
#ifdef ENABLE_TRACE_API_CALLS
#define TRACE_API_CALLS(x) cerr <<(x)<<"\n"
#else
#define TRACE_API_CALLS(x)
#endif

#include "vp2BlinnShader.h"

// Node id
MTypeId vp2BlinnShader::id( 0x00081102 );
// Node attributes
MObject vp2BlinnShader::aColor;
MObject vp2BlinnShader::aTransparency;
MObject vp2BlinnShader::aSpecularColor;
MObject vp2BlinnShader::aNonTexturedColor;
MObject vp2BlinnShader::aNonTexturedTransparency;

MObject vp2BlinnShader::aAddFragment;

///////////////////////////////////////////////////////////////////////////////////////////
// Node methods
///////////////////////////////////////////////////////////////////////////////////////////
void * vp2BlinnShader::creator()
{
TRACE_API_CALLS("vp2BlinnShader::creator");
return new vp2BlinnShader();
}

vp2BlinnShader::vp2BlinnShader()
{
TRACE_API_CALLS("vp2BlinnShader::vp2BlinnShader");
}

vp2BlinnShader::~vp2BlinnShader()
{
TRACE_API_CALLS("vp2BlinnShader::~vp2BlinnShader");
}

MStatus vp2BlinnShader::initialize()
{
// Shader attributes for the node
// They have been created to match internal parameters of the
// hardware shader instance
//
TRACE_API_CALLS("vp2BlinnShader::initialize");
MFnNumericAttribute nAttr;

// Create textured mode input attributes
MStatus result;
aAddFragment = nAttr.create("addFragment", "adf", MFnNumericData::kBoolean);
result = nAttr.setStorable(true);
result = nAttr.setKeyable(true);
result = nAttr.setDefault(false);
result = nAttr.setCached(true);
result = nAttr.setInternal(true);
result = nAttr.setAffectsAppearance(false);

aColor = nAttr.createColor( "color", "c");
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(0.6f, 0.6f, 0.6f);
nAttr.setAffectsAppearance( true );

aTransparency = nAttr.create( "transparency", "tr", MFnNumericData::kFloat );
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(0.0f);
nAttr.setMax(1.0f);
nAttr.setMin(0.0f);
nAttr.setAffectsAppearance( true );

aSpecularColor = nAttr.createColor( "specularColor", "sc" );
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(1.0f, 1.0f, 1.0f);
nAttr.setAffectsAppearance( true );

// Create non-textured mode input attributes
aNonTexturedColor = nAttr.createColor( "nonTexturedColor", "nc");
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(1.0f, 0.0f, 0.0f);
nAttr.setAffectsAppearance( true );

aNonTexturedTransparency = nAttr.create( "nonTexturedTransparency", "nt", MFnNumericData::kFloat );
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(0.0f);
nAttr.setMax(1.0f);
nAttr.setMin(0.0f);
nAttr.setAffectsAppearance( true );

 

// create output attributes here
// outColor is the only output attribute and it is inherited
// so we do not need to create or add it.
//

// Add the attributes to the node
addAttribute(aAddFragment);
addAttribute(aColor);
addAttribute(aTransparency);
addAttribute(aSpecularColor);
addAttribute(aNonTexturedColor);
addAttribute(aNonTexturedTransparency);

attributeAffects (aAddFragment, outColor);
attributeAffects (aColor, outColor);
attributeAffects (aTransparency, outColor);
attributeAffects (aSpecularColor, outColor);
attributeAffects (aNonTexturedColor,outColor);
attributeAffects (aNonTexturedTransparency,outColor);

return MS::kSuccess;
}

//
// Very simplistic software compute for the Maya software renderer
// This code is not the focus of this plug-in example so just
// returns a constant color.
//
MStatus vp2BlinnShader::compute(
const MPlug& plug,
MDataBlock& block )
{
TRACE_API_CALLS("vp2BlinnShader::compute");

if ((plug != outColor) && (plug.parent() != outColor))
return MS::kUnknownParameter;

MFloatVector & color = block.inputValue( aColor ).asFloatVector();

// set output color attribute
MDataHandle outColorHandle = block.outputValue( outColor );
MFloatVector& outColor = outColorHandle.asFloatVector();
outColor = color;

outColorHandle.setClean();
return MS::kSuccess;
}

////////////////////////////////////////////////////////////////////////////////////
// Swatch rendering:
// Does not matter the mode for the viewport VP1 or VP2
// Uses material viewer utility which uses the VP2 render to draw the swatch.
////////////////////////////////////////////////////////////////////////////////////
MStatus vp2BlinnShader::renderSwatchImage( MImage & outImage )
{
if (MHWRender::MRenderer::theRenderer())
{
// Use some sample objects for display
MString meshSphere("meshTeapot");
MString meshShaderball("meshShaderball");

unsigned int targetW, targetH;
outImage.getSize(targetW, targetH);

return MHWRender::MRenderUtilities::renderMaterialViewerGeometry(targetW > 128 ? meshShaderball : meshSphere,
thisMObject(),
outImage,
MHWRender::MRenderUtilities::kPerspectiveCamera,
MHWRender::MRenderUtilities::kSwatchLight);
}
return MS::kSuccess;
}

////////////////////////////////////////////////////////////////////////////////////
// Viewport 2.0 shader override implementation
////////////////////////////////////////////////////////////////////////////////////
class vp2BlinnShaderOverride : public MHWRender::MPxShaderOverride
{
public:
// Static method to create a new override
static MHWRender::MPxShaderOverride* Creator(const MObject& obj)
{
return new vp2BlinnShaderOverride(obj);
}

// Release the textured and non-textured mode shaders.
virtual ~vp2BlinnShaderOverride()
{
MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();
if (theRenderer)
{
const MHWRender::MShaderManager* shaderMgr = theRenderer->getShaderManager();
if (shaderMgr)
{
if (fColorShaderInstance)
{
shaderMgr->releaseShader(fColorShaderInstance);
}
fColorShaderInstance = NULL;

if (fNonTexturedColorShaderInstance)
{
shaderMgr->releaseShader(fNonTexturedColorShaderInstance);
}
fColorShaderInstance = NULL;
}
}

}

// 1. Initialize phase
// For this plug-in we simply set up geometry requirements
// based on an MShaderInstance
//
virtual MString initialize(const MInitContext& initContext,
MInitFeedback& initFeedback)
{
TRACE_API_CALLS("vp2BlinnShaderOverride::initialize");

if (fColorShaderInstance)
{
// This plugin is using the utility method
// MPxShaderOverride::drawGeometry(). For DX11 drawing,
// a shader signature is required. We use
// the signature from the same MShaderInstance used to
// set the geometry requirements so that the signature
// will match the requirements.
//
addShaderSignature( *fColorShaderInstance );

// Set the geometry requirements based on the shader instance
setGeometryRequirements( *fColorShaderInstance );
}
return MString("Autodesk Maya vp2 Blinn Shader Override");
}

// 2. Update Phase
// Access the node attributes and cache the values to update
// during updateDevice()
//
virtual void updateDG(MObject object)
{
TRACE_API_CALLS("vp2BlinnShaderOverride::updateDG");

if (object == MObject::kNullObj)
return;

// Get the hardware shader node from the MObject.
vp2BlinnShader *shaderNode = (vp2BlinnShader *) MPxHardwareShader::getHardwareShaderPtr( object );
if (!shaderNode)
return;

// Cache any data from the node to local data members.
MStatus status;
bool addFragment = false;
MFnDependencyNode node(object, &status);
if (status)
{
node.findPlug("colorR").getValue(fDiffuse[0]);
node.findPlug("colorG").getValue(fDiffuse[1]);
node.findPlug("colorB").getValue(fDiffuse[2]);
node.findPlug("transparency").getValue(fTransparency);
fDiffuse[3] = 1.0f - fTransparency;

node.findPlug("specularColorR").getValue(fSpecular[0]);
node.findPlug("specularColorG").getValue(fSpecular[1]);
node.findPlug("specularColorB").getValue(fSpecular[2]);

node.findPlug("nonTexturedColorR").getValue(fNonTextured[0]);
node.findPlug("nonTexturedColorG").getValue(fNonTextured[1]);
node.findPlug("nonTexturedColorB").getValue(fNonTextured[2]);
float nonTextureTransparency = 0.0f;
node.findPlug("nonTexturedTransparency").getValue(nonTextureTransparency);
fNonTextured[3] = 1.0f - nonTextureTransparency;

node.findPlug("addFragment").getValue(addFragment);
if (FragmentStatus != addFragment)
{
reCreateShaderInstance(addFragment);
FragmentStatus = addFragment;
}
}
}

// 2. Update Phase
// Call into utility method to update the shader instance
// when device level update is allowed.
virtual void updateDevice()
{
updateShaderInstance();
}

// 2. Update Phase
// Transparency hint
virtual bool isTransparent()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::isTransparent");
return (fTransparency > 0.0f);
}

// 2. Update Phase
// There is nothing to do at the end of update.
// Method is included for debug tracing only.
virtual void endUpdate()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::endUpdate");
}

// 3. Draw Phase
// Return the shader instance used for rendering
virtual MHWRender::MShaderInstance* shaderInstance() const
{
TRACE_API_CALLS("vp2BlinnShaderOverride::shaderInstance");
return fColorShaderInstance;
}

// 3. Draw Phase
// Bind the shader on activateKey() and
// the termination occur in terminateKey().
virtual void activateKey(MHWRender::MDrawContext& context, const MString& key)
{
MString out("vp2BlinnShaderOverride::activateKey[");
out += key;
out += "]";
TRACE_API_CALLS(out.asChar());

fColorShaderInstance->bind( context );
std::cerr << "display mode no = " << context.getDisplayStyle() << std::endl;
}

// 3. Draw Phase
// Use custom shader instance
//
virtual bool draw(MHWRender::MDrawContext& context,
const MHWRender::MRenderItemList& renderItemList) const
{
MString out("vp2BlinnShaderOverride::draw[Count=");
out += renderItemList.length();
out += "]";
TRACE_API_CALLS(out);

// Activate all the shader passes and draw using internal draw methods.
unsigned int passCount = fColorShaderInstance->getPassCount( context );
for (unsigned int i=0; i<passCount; i++)
{
fColorShaderInstance->activatePass( context, i );
MHWRender::MPxShaderOverride::drawGeometry(context);
}

return true;
}

// 3. Draw Phase
// Unbind / terminate the shader instance here.
virtual void terminateKey(MHWRender::MDrawContext& context, const MString& key)
{
MString out("vp2BlinnShaderOverride::terminateKey[");
out += key;
out += "]";
TRACE_API_CALLS(out.asChar());

// Unbind the shader
fColorShaderInstance->unbind( context );
}


// We are using an internal resources so we support all draw APIs
// automatically.
virtual MHWRender::DrawAPI supportedDrawAPIs() const
{
return (MHWRender::kOpenGL | MHWRender::kDirectX11 | MHWRender::kOpenGLCoreProfile);
}

// Supply a shader instance to be used when in non-textured mode. This
// allows for identification of objects using the "non-textured" mode color.
//
virtual MHWRender::MShaderInstance* nonTexturedShaderInstance(bool &monitor) const
{
TRACE_API_CALLS("vp2BlinnShaderOverride::nonTexturedShaderInstance");
if (fNonTexturedColorShaderInstance)
{
monitor = true;
// Mark whether the shader is transparent or not
fNonTexturedColorShaderInstance->setIsTransparent( fNonTextured[3] != 1.0f );
return fNonTexturedColorShaderInstance;
}
return NULL;
}

protected:
//
// Update the shader using the values cached during DG evaluation
// Called from updateDevice() during update phase.
//
void updateShaderInstance()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::updateShaderInstance");
if (FragmentStatus)
{
if (fColorShaderInstance)
{
// Update shader to mark it as drawing with transparency or not.
fColorShaderInstance->setIsTransparent(false);
}
if (fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance->setIsTransparent(false);
}
}
else
{
if (fColorShaderInstance)
{
// Update shader to mark it as drawing with transparency or not.
fColorShaderInstance->setIsTransparent(isTransparent());
fColorShaderInstance->setParameter("diffuseColor", &fDiffuse[0]);
fColorShaderInstance->setParameter("specularColor", &fSpecular[0]);
}
if (fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
fNonTexturedColorShaderInstance->setIsTransparent(fNonTextured[3] != 1.0f);
}
}
}

// Code to create MShaderInstances using a stock internal Blinn shader
// Create one shader for textured mode and one for non-textured mode.
//
void createShaderInstance()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::createShaderInstance");

MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
const MHWRender::MShaderManager* shaderMgr = renderer ? renderer->getShaderManager() : NULL;
if (!shaderMgr)
return;

if (!fColorShaderInstance)
{
fColorShaderInstance = shaderMgr->getStockShader( MHWRender::MShaderManager::k3dBlinnShader );
}
if (!fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance = shaderMgr->getStockShader( MHWRender::MShaderManager::k3dBlinnShader );
if (fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
}
}
}

void reCreateShaderInstance(bool addFragment)
{
TRACE_API_CALLS("vp2BlinnShaderOverride::createShaderInstance");

MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
const MHWRender::MShaderManager* shaderMgr = renderer ? renderer->getShaderManager() : NULL;
if (!shaderMgr)
return;
MHWRender::MFragmentManager* fragmentMgr =
renderer->getFragmentManager();
if (!fragmentMgr)
return;

//clean existing shader instance
if (addFragment) //then add the fragment
{
AddTestFragment();
}
else //remove fragment
{
if (fragmentMgr->hasFragment(testFragmentName))
{
fragmentMgr->removeFragment(testFragmentName);
}
}


shaderMgr->releaseShader(fColorShaderInstance);
fColorShaderInstance = nullptr;
shaderMgr->releaseShader(fNonTexturedColorShaderInstance);
fNonTexturedColorShaderInstance = nullptr;

shaderMgr->clearEffectCache();

MStatus result;
if (!fColorShaderInstance)
{
fColorShaderInstance = shaderMgr->getStockShader(MHWRender::MShaderManager::k3dBlinnShader);
if (addFragment) //then add the fragment
{
result = fColorShaderInstance->addInputFragment(testFragmentName, "outTestColor", "diffuseColor");
}
}
if (!fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance = shaderMgr->getStockShader(MHWRender::MShaderManager::k3dBlinnShader);
if (fNonTexturedColorShaderInstance)
{
if (addFragment) //then add the fragment
{
result = fNonTexturedColorShaderInstance->addInputFragment(testFragmentName, "outTestColor", "diffuseColor");
}
else
{
fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
}
}
}


}

void AddTestFragment()
{
MString fragmentName("testFragment");
static const char* nonTexturedFragmentBodyBsdf =
"<fragment uiName=\"testFragment\" name=\"testFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">"
" <description><![CDATA[Simple file texture fragment]]></description>"
" <properties>"
" </properties>"
" <values>"
" </values>"
" <outputs>"
" <float3 name=\"outTestColor\" />"
" </outputs>"
" <implementation>"
" <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.100000\">"
" <function_name val=\"testFragment\" />"
" <source><![CDATA["
"float3 testFragment() \n"
"{ \n"
" return float3(0.0, 0.0, 0.0); \n"
"} \n]]>"
" </source>"
" </implementation>"
" <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.000000\">"
" <function_name val=\"testFragment\" />"
" <source><![CDATA["
"float3 testFragment() \n"
"{ \n"
" return float3(0.0, 0.0, 0.0); \n"
"} \n]]>"
" </source>"
" </implementation>"
" <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">"
" <function_name val=\"testFragment\" />"
" <source><![CDATA["
"vec3 testFragment() \n"
"{ \n"
" return vec3(0.0, 0.5, 0.5); \n"
"} \n]]>"
" </source>"
" </implementation>"
" </implementation>"
"</fragment>";

testFragmentName = "";
MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();

if (theRenderer)
{
MHWRender::MFragmentManager* fragmentMgr =
theRenderer->getFragmentManager();
if (fragmentMgr)
{
// Add fragments if needed
bool fragAdded = fragmentMgr->hasFragment(fragmentName);
if (!fragAdded)
{
fragAdded = (fragmentName == fragmentMgr->addShadeFragmentFromBuffer(nonTexturedFragmentBodyBsdf, false));
}

if (fragAdded)
{
testFragmentName = fragmentName;
}
}
}
}
//
// Constructor. Simply initialize shader instances for usage.
//
vp2BlinnShaderOverride(const MObject& obj)
: MHWRender::MPxShaderOverride(obj)
, fColorShaderInstance(NULL)
, fNonTexturedColorShaderInstance(NULL)
, fTransparency(0.0f)
{
fDiffuse[0] = fDiffuse[1] = fDiffuse[2] = fDiffuse[3] = 0.0f;
fSpecular[0] = fSpecular[1] = fSpecular[2] = 0.0f;
fNonTextured[0] = 1.0; fNonTextured[1] = fNonTextured[2] = 0.0f;
fNonTextured[3] = 1.0f;

fNewColor[0] = 1.0; fNewColor[1] = fNewColor[2] = 0.0f;
FragmentStatus = false;
testFragmentName = "";

// Create a shader instance to use for drawing
//
createShaderInstance();
}

// Cached shader inputs values
float fTransparency;
float fDiffuse[4];
float fSpecular[3];
float fShininess[3];
float fNonTextured[4];

float fNewColor[4];
bool FragmentStatus;
MString testFragmentName;

// Shader to use to draw with
MHWRender::MShaderInstance *fColorShaderInstance;
// Shader to use to draw non-textured with
MHWRender::MShaderInstance *fNonTexturedColorShaderInstance;
};

/////////////////////////////////////////////////////////////////////////////////////////
// Plug-in handling
/////////////////////////////////////////////////////////////////////////////////////////
static const MString svp2BlinnShaderRegistrantId("vp2BlinnShaderRegistrantId");

// Note that we use the same drawdb classification for both registerNode()
// and registerShaderOverrideCreator() to associate the override with the Maya node.
//
MStatus initializePlugin( MObject obj )
{
TRACE_API_CALLS("initializePlugin");
MStatus status;

const MString& swatchName = MHWShaderSwatchGenerator::initialize();
const MString UserClassify( "shader/surface/utility/:drawdb/shader/surface/vp2BlinnShader:swatch/"+swatchName);

MFnPlugin plugin( obj, PLUGIN_COMPANY, "1.0", "Any");
status = plugin.registerNode( "vp2BlinnShader", vp2BlinnShader::id,
vp2BlinnShader::creator, vp2BlinnShader::initialize,
MPxNode::kHardwareShader, &UserClassify );
if (!status) {
status.perror("registerNode");
return status;
}

// Register a shader override for this node
MHWRender::MDrawRegistry::registerShaderOverrideCreator(
"drawdb/shader/surface/vp2BlinnShader",
svp2BlinnShaderRegistrantId,
vp2BlinnShaderOverride::Creator);
if (status != MS::kSuccess) return status;

return MS::kSuccess;
}

MStatus uninitializePlugin( MObject obj )
{
TRACE_API_CALLS("uninitializePlugin");
MStatus status;

MFnPlugin plugin( obj );

// Unregister the shader node
plugin.deregisterNode( vp2BlinnShader::id );
if (!status) {
status.perror("deregisterNode");
return status;
}

// Deregister the shader override
status = MHWRender::MDrawRegistry::deregisterShaderOverrideCreator(
"drawdb/shader/surface/vp2BlinnShader", svp2BlinnShaderRegistrantId);
if (status != MS::kSuccess) return status;


MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
if (renderer)
{
const MHWRender::MShaderManager* shaderMgr = renderer ? renderer->getShaderManager() : NULL;
if (shaderMgr)
shaderMgr->clearEffectCache();
}

return MS::kSuccess;
}

 

 

//-
// ==========================================================================
// Copyright 2015 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+
#include <maya/MIOStream.h>
#include <math.h>
#include <cstdlib>

//#include <maya/MGlobal.h>
#include <maya/MString.h>
#include <maya/MPlug.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnDependencyNode.h>
//#include <maya/MUserData.h>

//#include <maya/MHardwareRenderer.h>

// Includes for swatch rendering
#include <maya/MHWShaderSwatchGenerator.h>
#include <maya/MImage.h>
#include <maya/MRenderUtilities.h>

#include <maya/MMatrix.h>

// Viewport 2.0 includes
#include <maya/MDrawRegistry.h>
#include <maya/MPxShaderOverride.h>
#include <maya/MDrawContext.h>
#include <maya/MStateManager.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MShaderManager.h>

//include for adding fragment
#include <maya/MFragmentManager.h>

#undef ENABLE_TRACE_API_CALLS
//#define ENABLE_TRACE_API_CALLS 1
#ifdef ENABLE_TRACE_API_CALLS
#define TRACE_API_CALLS(x) cerr <<(x)<<"\n"
#else
#define TRACE_API_CALLS(x)
#endif

#include "vp2BlinnShader.h"

// Node id
MTypeId vp2BlinnShader::id( 0x00081102 );
// Node attributes
MObject vp2BlinnShader::aColor;
MObject vp2BlinnShader::aTransparency;
MObject vp2BlinnShader::aSpecularColor;
MObject vp2BlinnShader::aNonTexturedColor;
MObject vp2BlinnShader::aNonTexturedTransparency;

MObject vp2BlinnShader::aAddFragment;

///////////////////////////////////////////////////////////////////////////////////////////
// This plug-in implementation shows the usage of an MPxShaderOverride for
// a Maya shader node.
//
// The purpose is to show as simple a plug-in as possible without worrying
// about the details of trying to write a shader system.
//
// As such it attempts to (re)use as many internal VP2 API
// intterfaces and constructs as possible.
//
// In this case the plug-in will use a stock shader instance (MShaderInstance)
// as it's single internal shader. As part of initialization it will reuse
// internal MShaderInstance utility methods to show how a DX11 shader signature
// can be set as as well as how to return the vertex requirements simply.
// As there is only one shader instance the shader key used is also simplistic
// as it can be a constant value.
//
// Transparency notificaiton is handle by setting the MPxShaderOverride::isTransparent()
// virtual method return value appropriately based on node attribute values.
//
// The code also demonstrates handling of non-textured draw by providing another stock
// MShaderInstance to be returned from MPxShaderOverride::nonTexturedShaderInstance()
// It will also handle transparency by appropriately updating the shader instance
// transparency hint using MShaderInstance::setIsTransparent().
//
// For update, the node attributes match a few of the MShaderInstance parameters
// to show DG update and device update. Additional attributes are added to
// show how the non-texture mode shader instance parameters can be driven
// by attribute changes.
//
// For drawing, the code reuses the internally provided binding interfaces on
// MShaderInstance as well as the utility geometry drawing method:
// MPxShaderOverride::drawGeometry().
//
// For swatch rendering the basic VP2 supplied utility
// MRenderUtilities::renderMaterialViewerGeometry() is used.
//
// (De)registration is shown as part of plug-in (de)initialization, noting
// that the MPxShaderOverride association to the MPxNode node is achieved
// by supplying the same "drawdb/shader" classification for both registration
// interfaces.
//
///////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////
// Node methods
///////////////////////////////////////////////////////////////////////////////////////////
void * vp2BlinnShader::creator()
{
TRACE_API_CALLS("vp2BlinnShader::creator");
return new vp2BlinnShader();
}

vp2BlinnShader::vp2BlinnShader()
{
TRACE_API_CALLS("vp2BlinnShader::vp2BlinnShader");
}

vp2BlinnShader::~vp2BlinnShader()
{
TRACE_API_CALLS("vp2BlinnShader::~vp2BlinnShader");
}

MStatus vp2BlinnShader::initialize()
{
// Shader attributes for the node
// They have been created to match internal parameters of the
// hardware shader instance
//
TRACE_API_CALLS("vp2BlinnShader::initialize");
MFnNumericAttribute nAttr;

// Create textured mode input attributes
MStatus result;
aAddFragment = nAttr.create("addFragment", "adf", MFnNumericData::kBoolean);
result = nAttr.setStorable(true);
result = nAttr.setKeyable(true);
result = nAttr.setDefault(false);
result = nAttr.setCached(true);
result = nAttr.setInternal(true);
result = nAttr.setAffectsAppearance(false);

aColor = nAttr.createColor( "color", "c");
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(0.6f, 0.6f, 0.6f);
nAttr.setAffectsAppearance( true );

aTransparency = nAttr.create( "transparency", "tr", MFnNumericData::kFloat );
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(0.0f);
nAttr.setMax(1.0f);
nAttr.setMin(0.0f);
nAttr.setAffectsAppearance( true );

aSpecularColor = nAttr.createColor( "specularColor", "sc" );
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(1.0f, 1.0f, 1.0f);
nAttr.setAffectsAppearance( true );

// Create non-textured mode input attributes
aNonTexturedColor = nAttr.createColor( "nonTexturedColor", "nc");
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(1.0f, 0.0f, 0.0f);
nAttr.setAffectsAppearance( true );

aNonTexturedTransparency = nAttr.create( "nonTexturedTransparency", "nt", MFnNumericData::kFloat );
nAttr.setStorable(true);
nAttr.setKeyable(true);
nAttr.setDefault(0.0f);
nAttr.setMax(1.0f);
nAttr.setMin(0.0f);
nAttr.setAffectsAppearance( true );

 

// create output attributes here
// outColor is the only output attribute and it is inherited
// so we do not need to create or add it.
//

// Add the attributes to the node
addAttribute(aAddFragment);
addAttribute(aColor);
addAttribute(aTransparency);
addAttribute(aSpecularColor);
addAttribute(aNonTexturedColor);
addAttribute(aNonTexturedTransparency);

attributeAffects (aAddFragment, outColor);
attributeAffects (aColor, outColor);
attributeAffects (aTransparency, outColor);
attributeAffects (aSpecularColor, outColor);
attributeAffects (aNonTexturedColor,outColor);
attributeAffects (aNonTexturedTransparency,outColor);

return MS::kSuccess;
}

//
// Very simplistic software compute for the Maya software renderer
// This code is not the focus of this plug-in example so just
// returns a constant color.
//
MStatus vp2BlinnShader::compute(
const MPlug& plug,
MDataBlock& block )
{
TRACE_API_CALLS("vp2BlinnShader::compute");

if ((plug != outColor) && (plug.parent() != outColor))
return MS::kUnknownParameter;

MFloatVector & color = block.inputValue( aColor ).asFloatVector();

// set output color attribute
MDataHandle outColorHandle = block.outputValue( outColor );
MFloatVector& outColor = outColorHandle.asFloatVector();
outColor = color;

outColorHandle.setClean();
return MS::kSuccess;
}

////////////////////////////////////////////////////////////////////////////////////
// Swatch rendering:
// Does not matter the mode for the viewport VP1 or VP2
// Uses material viewer utility which uses the VP2 render to draw the swatch.
////////////////////////////////////////////////////////////////////////////////////
MStatus vp2BlinnShader::renderSwatchImage( MImage & outImage )
{
if (MHWRender::MRenderer::theRenderer())
{
// Use some sample objects for display
MString meshSphere("meshTeapot");
MString meshShaderball("meshShaderball");

unsigned int targetW, targetH;
outImage.getSize(targetW, targetH);

return MHWRender::MRenderUtilities::renderMaterialViewerGeometry(targetW > 128 ? meshShaderball : meshSphere,
thisMObject(),
outImage,
MHWRender::MRenderUtilities::kPerspectiveCamera,
MHWRender::MRenderUtilities::kSwatchLight);
}
return MS::kSuccess;
}

////////////////////////////////////////////////////////////////////////////////////
// Viewport 2.0 shader override implementation
////////////////////////////////////////////////////////////////////////////////////
class vp2BlinnShaderOverride : public MHWRender::MPxShaderOverride
{
public:
// Static method to create a new override
static MHWRender::MPxShaderOverride* Creator(const MObject& obj)
{
return new vp2BlinnShaderOverride(obj);
}

// Release the textured and non-textured mode shaders.
virtual ~vp2BlinnShaderOverride()
{
MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();
if (theRenderer)
{
const MHWRender::MShaderManager* shaderMgr = theRenderer->getShaderManager();
if (shaderMgr)
{
if (fColorShaderInstance)
{
shaderMgr->releaseShader(fColorShaderInstance);
}
fColorShaderInstance = NULL;

if (fNonTexturedColorShaderInstance)
{
shaderMgr->releaseShader(fNonTexturedColorShaderInstance);
}
fColorShaderInstance = NULL;
}
}

}

// 1. Initialize phase
// For this plug-in we simply set up geometry requirements
// based on an MShaderInstance
//
virtual MString initialize(const MInitContext& initContext,
MInitFeedback& initFeedback)
{
TRACE_API_CALLS("vp2BlinnShaderOverride::initialize");

if (fColorShaderInstance)
{
// This plugin is using the utility method
// MPxShaderOverride::drawGeometry(). For DX11 drawing,
// a shader signature is required. We use
// the signature from the same MShaderInstance used to
// set the geometry requirements so that the signature
// will match the requirements.
//
addShaderSignature( *fColorShaderInstance );

// Set the geometry requirements based on the shader instance
setGeometryRequirements( *fColorShaderInstance );
}
return MString("Autodesk Maya vp2 Blinn Shader Override");
}

// 2. Update Phase
// Access the node attributes and cache the values to update
// during updateDevice()
//
virtual void updateDG(MObject object)
{
TRACE_API_CALLS("vp2BlinnShaderOverride::updateDG");

if (object == MObject::kNullObj)
return;

// Get the hardware shader node from the MObject.
vp2BlinnShader *shaderNode = (vp2BlinnShader *) MPxHardwareShader::getHardwareShaderPtr( object );
if (!shaderNode)
return;

// Cache any data from the node to local data members.
MStatus status;
bool addFragment = false;
MFnDependencyNode node(object, &status);
if (status)
{
node.findPlug("colorR").getValue(fDiffuse[0]);
node.findPlug("colorG").getValue(fDiffuse[1]);
node.findPlug("colorB").getValue(fDiffuse[2]);
node.findPlug("transparency").getValue(fTransparency);
fDiffuse[3] = 1.0f - fTransparency;

node.findPlug("specularColorR").getValue(fSpecular[0]);
node.findPlug("specularColorG").getValue(fSpecular[1]);
node.findPlug("specularColorB").getValue(fSpecular[2]);

node.findPlug("nonTexturedColorR").getValue(fNonTextured[0]);
node.findPlug("nonTexturedColorG").getValue(fNonTextured[1]);
node.findPlug("nonTexturedColorB").getValue(fNonTextured[2]);
float nonTextureTransparency = 0.0f;
node.findPlug("nonTexturedTransparency").getValue(nonTextureTransparency);
fNonTextured[3] = 1.0f - nonTextureTransparency;

node.findPlug("addFragment").getValue(addFragment);
if (FragmentStatus != addFragment)
{
reCreateShaderInstance(addFragment);
FragmentStatus = addFragment;
}
}
}

// 2. Update Phase
// Call into utility method to update the shader instance
// when device level update is allowed.
virtual void updateDevice()
{
updateShaderInstance();
}

// 2. Update Phase
// Transparency hint
virtual bool isTransparent()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::isTransparent");
return (fTransparency > 0.0f);
}

// 2. Update Phase
// There is nothing to do at the end of update.
// Method is included for debug tracing only.
virtual void endUpdate()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::endUpdate");
}

// 3. Draw Phase
// Return the shader instance used for rendering
virtual MHWRender::MShaderInstance* shaderInstance() const
{
TRACE_API_CALLS("vp2BlinnShaderOverride::shaderInstance");
return fColorShaderInstance;
}

// 3. Draw Phase
// Bind the shader on activateKey() and
// the termination occur in terminateKey().
virtual void activateKey(MHWRender::MDrawContext& context, const MString& key)
{
MString out("vp2BlinnShaderOverride::activateKey[");
out += key;
out += "]";
TRACE_API_CALLS(out.asChar());

fColorShaderInstance->bind( context );
std::cerr << "display mode no = " << context.getDisplayStyle() << std::endl;
}

// 3. Draw Phase
// Use custom shader instance
//
virtual bool draw(MHWRender::MDrawContext& context,
const MHWRender::MRenderItemList& renderItemList) const
{
MString out("vp2BlinnShaderOverride::draw[Count=");
out += renderItemList.length();
out += "]";
TRACE_API_CALLS(out);

// Activate all the shader passes and draw using internal draw methods.
unsigned int passCount = fColorShaderInstance->getPassCount( context );
for (unsigned int i=0; i<passCount; i++)
{
fColorShaderInstance->activatePass( context, i );
MHWRender::MPxShaderOverride::drawGeometry(context);
}

return true;
}

// 3. Draw Phase
// Unbind / terminate the shader instance here.
virtual void terminateKey(MHWRender::MDrawContext& context, const MString& key)
{
MString out("vp2BlinnShaderOverride::terminateKey[");
out += key;
out += "]";
TRACE_API_CALLS(out.asChar());

// Unbind the shader
fColorShaderInstance->unbind( context );
}


// We are using an internal resources so we support all draw APIs
// automatically.
virtual MHWRender::DrawAPI supportedDrawAPIs() const
{
return (MHWRender::kOpenGL | MHWRender::kDirectX11 | MHWRender::kOpenGLCoreProfile);
}

// Supply a shader instance to be used when in non-textured mode. This
// allows for identification of objects using the "non-textured" mode color.
//
virtual MHWRender::MShaderInstance* nonTexturedShaderInstance(bool &monitor) const
{
TRACE_API_CALLS("vp2BlinnShaderOverride::nonTexturedShaderInstance");
if (fNonTexturedColorShaderInstance)
{
monitor = true;
// Mark whether the shader is transparent or not
fNonTexturedColorShaderInstance->setIsTransparent( fNonTextured[3] != 1.0f );
return fNonTexturedColorShaderInstance;
}
return NULL;
}

protected:
//
// Update the shader using the values cached during DG evaluation
// Called from updateDevice() during update phase.
//
void updateShaderInstance()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::updateShaderInstance");
if (FragmentStatus)
{
if (fColorShaderInstance)
{
// Update shader to mark it as drawing with transparency or not.
fColorShaderInstance->setIsTransparent(false);
}
if (fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance->setIsTransparent(false);
}
}
else
{
if (fColorShaderInstance)
{
// Update shader to mark it as drawing with transparency or not.
fColorShaderInstance->setIsTransparent(isTransparent());
fColorShaderInstance->setParameter("diffuseColor", &fDiffuse[0]);
fColorShaderInstance->setParameter("specularColor", &fSpecular[0]);
}
if (fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
fNonTexturedColorShaderInstance->setIsTransparent(fNonTextured[3] != 1.0f);
}
}
}

// Code to create MShaderInstances using a stock internal Blinn shader
// Create one shader for textured mode and one for non-textured mode.
//
void createShaderInstance()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::createShaderInstance");

MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
const MHWRender::MShaderManager* shaderMgr = renderer ? renderer->getShaderManager() : NULL;
if (!shaderMgr)
return;

if (!fColorShaderInstance)
{
fColorShaderInstance = shaderMgr->getStockShader( MHWRender::MShaderManager::k3dBlinnShader );
}
if (!fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance = shaderMgr->getStockShader( MHWRender::MShaderManager::k3dBlinnShader );
if (fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
}
}
}

void reCreateShaderInstance(bool addFragment)
{
TRACE_API_CALLS("vp2BlinnShaderOverride::createShaderInstance");

MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
const MHWRender::MShaderManager* shaderMgr = renderer ? renderer->getShaderManager() : NULL;
if (!shaderMgr)
return;
MHWRender::MFragmentManager* fragmentMgr =
renderer->getFragmentManager();
if (!fragmentMgr)
return;

//clean existing shader instance
if (addFragment) //then add the fragment
{
AddTestFragment();
}
else //remove fragment
{
if (fragmentMgr->hasFragment(testFragmentName))
{
fragmentMgr->removeFragment(testFragmentName);
}
}


shaderMgr->releaseShader(fColorShaderInstance);
fColorShaderInstance = nullptr;
shaderMgr->releaseShader(fNonTexturedColorShaderInstance);
fNonTexturedColorShaderInstance = nullptr;

shaderMgr->clearEffectCache();

MStatus result;
if (!fColorShaderInstance)
{
fColorShaderInstance = shaderMgr->getStockShader(MHWRender::MShaderManager::k3dBlinnShader);
if (addFragment) //then add the fragment
{
result = fColorShaderInstance->addInputFragment(testFragmentName, "outTestColor", "diffuseColor");
}
}
if (!fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance = shaderMgr->getStockShader(MHWRender::MShaderManager::k3dBlinnShader);
if (fNonTexturedColorShaderInstance)
{
if (addFragment) //then add the fragment
{
result = fNonTexturedColorShaderInstance->addInputFragment(testFragmentName, "outTestColor", "diffuseColor");
}
else
{
fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
}
}
}


}

void AddTestFragment()
{
MString fragmentName("testFragment");
static const char* nonTexturedFragmentBodyBsdf =
"<fragment uiName=\"testFragment\" name=\"testFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">"
" <description><![CDATA[Simple file texture fragment]]></description>"
" <properties>"
" </properties>"
" <values>"
" </values>"
" <outputs>"
" <float3 name=\"outTestColor\" />"
" </outputs>"
" <implementation>"
" <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.100000\">"
" <function_name val=\"testFragment\" />"
" <source><![CDATA["
"float3 testFragment() \n"
"{ \n"
" return float3(0.0, 0.0, 0.0); \n"
"} \n]]>"
" </source>"
" </implementation>"
" <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.000000\">"
" <function_name val=\"testFragment\" />"
" <source><![CDATA["
"float3 testFragment() \n"
"{ \n"
" return float3(0.0, 0.0, 0.0); \n"
"} \n]]>"
" </source>"
" </implementation>"
" <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">"
" <function_name val=\"testFragment\" />"
" <source><![CDATA["
"vec3 testFragment() \n"
"{ \n"
" return vec3(0.0, 0.5, 0.5); \n"
"} \n]]>"
" </source>"
" </implementation>"
" </implementation>"
"</fragment>";

testFragmentName = "";
MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();

if (theRenderer)
{
MHWRender::MFragmentManager* fragmentMgr =
theRenderer->getFragmentManager();
if (fragmentMgr)
{
// Add fragments if needed
bool fragAdded = fragmentMgr->hasFragment(fragmentName);
if (!fragAdded)
{
fragAdded = (fragmentName == fragmentMgr->addShadeFragmentFromBuffer(nonTexturedFragmentBodyBsdf, false));
}

if (fragAdded)
{
testFragmentName = fragmentName;
}
}
}
}
//
// Constructor. Simply initialize shader instances for usage.
//
vp2BlinnShaderOverride(const MObject& obj)
: MHWRender::MPxShaderOverride(obj)
, fColorShaderInstance(NULL)
, fNonTexturedColorShaderInstance(NULL)
, fTransparency(0.0f)
{
fDiffuse[0] = fDiffuse[1] = fDiffuse[2] = fDiffuse[3] = 0.0f;
fSpecular[0] = fSpecular[1] = fSpecular[2] = 0.0f;
fNonTextured[0] = 1.0; fNonTextured[1] = fNonTextured[2] = 0.0f;
fNonTextured[3] = 1.0f;

fNewColor[0] = 1.0; fNewColor[1] = fNewColor[2] = 0.0f;
FragmentStatus = false;
testFragmentName = "";

// Create a shader instance to use for drawing
//
createShaderInstance();
}

// Cached shader inputs values
float fTransparency;
float fDiffuse[4];
float fSpecular[3];
float fShininess[3];
float fNonTextured[4];

float fNewColor[4];
bool FragmentStatus;
MString testFragmentName;

// Shader to use to draw with
MHWRender::MShaderInstance *fColorShaderInstance;
// Shader to use to draw non-textured with
MHWRender::MShaderInstance *fNonTexturedColorShaderInstance;
};

/////////////////////////////////////////////////////////////////////////////////////////
// Plug-in handling
/////////////////////////////////////////////////////////////////////////////////////////
static const MString svp2BlinnShaderRegistrantId("vp2BlinnShaderRegistrantId");

// Note that we use the same drawdb classification for both registerNode()
// and registerShaderOverrideCreator() to associate the override with the Maya node.
//
MStatus initializePlugin( MObject obj )
{
TRACE_API_CALLS("initializePlugin");
MStatus status;

const MString& swatchName = MHWShaderSwatchGenerator::initialize();
const MString UserClassify( "shader/surface/utility/:drawdb/shader/surface/vp2BlinnShader:swatch/"+swatchName);

MFnPlugin plugin( obj, PLUGIN_COMPANY, "1.0", "Any");
status = plugin.registerNode( "vp2BlinnShader", vp2BlinnShader::id,
vp2BlinnShader::creator, vp2BlinnShader::initialize,
MPxNode::kHardwareShader, &UserClassify );
if (!status) {
status.perror("registerNode");
return status;
}

// Register a shader override for this node
MHWRender::MDrawRegistry::registerShaderOverrideCreator(
"drawdb/shader/surface/vp2BlinnShader",
svp2BlinnShaderRegistrantId,
vp2BlinnShaderOverride::Creator);
if (status != MS::kSuccess) return status;

return MS::kSuccess;
}

MStatus uninitializePlugin( MObject obj )
{
TRACE_API_CALLS("uninitializePlugin");
MStatus status;

MFnPlugin plugin( obj );

// Unregister the shader node
plugin.deregisterNode( vp2BlinnShader::id );
if (!status) {
status.perror("deregisterNode");
return status;
}

// Deregister the shader override
status = MHWRender::MDrawRegistry::deregisterShaderOverrideCreator(
"drawdb/shader/surface/vp2BlinnShader", svp2BlinnShaderRegistrantId);
if (status != MS::kSuccess) return status;


MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
if (renderer)
{
const MHWRender::MShaderManager* shaderMgr = renderer ? renderer->getShaderManager() : NULL;
if (shaderMgr)
shaderMgr->clearEffectCache();
}

return MS::kSuccess;
}

 

The header code is as below 

#ifndef _vp2BlinnShader
#define _vp2BlinnShader
//-
// ==========================================================================
// Copyright 2015 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+
#include <maya/MPxHardwareShader.h>
#include <maya/MRenderProfile.h>

class vp2BlinnShader : public MPxHardwareShader
{
public:
vp2BlinnShader();
virtual ~vp2BlinnShader();

virtual MStatus compute( const MPlug&, MDataBlock& );

// VP1 profile. Just leave as unsupported hardware profile
// as sample code.
virtual const MRenderProfile & profile()
{
static MRenderProfile sProfile;
if(sProfile.numberOfRenderers() == 0)
sProfile.addRenderer(MRenderProfile::kMayaSoftware);
return sProfile;
}

// Swatch rendering. Called irregardless of VP1 or VP2.
//
virtual MStatus renderSwatchImage( MImage & image );

static void * creator();
static MStatus initialize();

static MTypeId id;

protected:

private:
// Attributes
static MObject aColor;
static MObject aTransparency;
static MObject aDiffuseColor;
static MObject aSpecularColor;
static MObject aNonTexturedColor;
static MObject aNonTexturedTransparency;

static MObject aAddFragment;
};

#endif /* _vp2BlinnShader */

 

let me know if you need more details.

 

Thanks

Dhiraj

0 Likes
Message 8 of 9

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

I think it should be a bug. It seems that new shader is not updated in Maya.

 

I've logged a defect in our system. Our engineers will take a look at it.

 

Yours,

Li

0 Likes
Message 9 of 9

Anonymous
Not applicable

Hi Li,

 

Thank you for the response and logging the defect.

Will be waiting for the fix. It would be great if you could provide an update once the fix is available.

 

Regards,

Dhiraj

0 Likes