Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

C++ shader Viewport 2.0 texture display

C++ shader Viewport 2.0 texture display

Anonymous
Not applicable
3,938 Views
25 Replies
Message 1 of 26

C++ shader Viewport 2.0 texture display

Anonymous
Not applicable

Hello All, 

 

I'm in the process of writing a shader but can't get the texture to display for VP2 or rather the parameter to set it to. 

(as a side note everything else works as well as for VP1)

 

 

 

for the MShaderInstance im using the k3dBlinnShader

 

 

I havent found any list of parameters for the stock shaders. 

 

 

the pixel data is acquired and set into a MTextureAssignment

 

 

0 Likes
Accepted solutions (1)
3,939 Views
25 Replies
Replies (25)
Message 2 of 26

cheng_xi_li
Autodesk Support
Autodesk Support

Hi cronicryo,

 

How do you try to get texture in VP2? Have you tried MTextureManager::acquireTexture?

 

Yours,

Li

0 Likes
Message 3 of 26

Anonymous
Not applicable

Thank you for your response. I literally was about to give up today.

 
 
yes i have used acquire texture.
 
 
i think the problem is that the data that im providing to the override is not what its looking for because my shader handles the color and it is not a direct link or something
 
first is how im getting the pixel data
this is just to be able to get a read of pixel data and would not be in the final implementation 
and it does work in both the MTexture and MImage i have written both to disk and the data is there.
 
 
 
 
MImage image;
MSelectionList selection;
selection.add("file1");
MObject obj;
selection.getDependNode(0, obj);

image.readFromTextureNode(obj);

image.resize(1024, 1024, false);
unsigned int width, height;
image.getSize(width, height);



MHWRender::MTextureDescription textureDesc;

textureDesc.setToDefault2DTexture();
textureDesc.fWidth = width;
textureDesc.fHeight = width;
textureDesc.fDepth = 1;
textureDesc.fBytesPerRow = 4*width;
textureDesc.fBytesPerSlice = 4*width*width;
textureDesc.fMipmaps = 1;
textureDesc.fArraySlices = 1;
textureDesc.fFormat = MHWRender::kR8G8B8A8_UNORM;
textureDesc.fTextureType = MHWRender::kImage2D;

MString newTextureName = MString("MyCustomTexture");
mColorTexture.texture = textureManager->acquireTexture(newTextureName, textureDesc, image.pixels());
//mColorTexture is a MTextureAssignment stored variable

 

 

so the first attempt i used MPxShaderOverride

which i was able to get the a solid color and not a texture mapped to diffuseColor

once the texture was mapped the cube with the shader assigned was orangeif i didnt set the solid color

(im pretty sure the orange is the default color if nothing is changed)

 

 

then the second attempt i used MPxSurfaceShadingNodeOverride

which almost brought me closer i was able to get a texture to work by using the getCustomMappings override and setting color to outGlowColor which if i mapped something it showed up but this wasnt the result i needed 

with this method i tried mapping color to outColor and this worked too except not for the texture.

my shader layers colors together with blend modes and with this same method the color changed and to reiterate once a texture was connected it turned didnt show the texture.

 

at this point my consensus was that without a direct connection it wasnt working

so now still using the MPxSurfaceShadingNodeOverride i tried with the mapping of color to outGlowColor and in the hypershade connecting outColor to outGlowColor  i still did not get the texture to show.

so to make sure that the outColor  was outputing properly i connected it into a layeredShader and it display fine in the thumbnail.

i also then tried connecting that layeredShader node into the outGlowColor and that still didnt work.

 

at this point im not sure what else to do or try. 

the documentation on VP2 is at its minimum and its very hard to find a custom solution when the examples that are given are ways to create a basic set up

 

 

Please Help! the studio im at uses an old old shader that was created and its been very useful except the there was no viewport set up and only worked in mental ray. i have implemented everything except VP2

 

Thanks, 

   Ryan

 

 

 

 

 

0 Likes
Message 4 of 26

cheng_xi_li
Autodesk Support
Autodesk Support

Hi cronicryo,

 

The acquireTexture code looks fine to me. MPxShaderOverrideNode::getCustomMappings() should be used for custom mapping parameter of your shader fragment.

 

According to your description, I think you are trying to use a k3dBlinnShader stock shader and want to add a texture as diffuseColor of it? In that case, you can use MShaderInstance::addInputFragment to apply a custom texture shader fragment as input for the diffuseColor of k3dBlinnShader stock shader. 

 

Once you have done that, the diffuseColor parameter can't be updated by MShaderInstance::setParameter; instead, you should update the parameter of your shader fragment.

 

Yours,

Li

0 Likes
Message 5 of 26

Anonymous
Not applicable

I had a feeling it was gonna come down to fragments. I tried doing a search
and again the help docs were limited on providing information.

I was looking at this for reference . But I'm not too certain of what I should take and use. At line
305 is where all the fragments are created and added. Do I need to recreate
all these sections for my shader as well?

I tried looking at the Xml schema but that doesn't explain much it just makes it more confusing because the third
section looks like what I need but it just says xml for fragment graph so
this just leaves me confused as to what it's called and what to look up.

Regards,
Ryan






--
Sent from Gmail Mobile

0 Likes
Message 6 of 26

Anonymous
Not applicable

Ok so i really hope you see this but im finally understanding what you mean by useing addInputFragement so right now i have this.

 

 mayaFileTexture is a built in fragment that i tried using.

 

fColorShaderInstance->addInputFragment("mayaFileTexture","outColor","diffuseColor" );

with furter investigaiton i spit out the xml of mayaFileTexture and the output name on the fragment is mayaFileTextureOutput

 

so i tried

 

fColorShaderInstance->addInputFragment("mayaFileTexture","mayaFileTextureOutput","diffuseColor" );

 

 

in both cases the MStatus returned:

(kUnknownParameter): Unexpected Internal Failure

 

 

im not sure what fragment i should be using or i should be creating my own and how

0 Likes
Message 7 of 26

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

I was writing a reply while you are posting new one. I'll just reply to the latest one.

 

The "mayaFileTexture" should be your fragment graph name. The output of original fileTexture example which uses a struct isn't fit for diffuseColor in blinn.

 

For your usage, I think the output fragment is no longer needed.

 

And for the shader part, the output should be float3, since diffuseColor is not a complex type.

 

In the fragment graph, the reference for output fragment is no longer needed and connection is not neither. The output should be a float3 type instead of struct.

 

And I think, the blinn attribute is not "diffuseColor", it should be "color".

 

P.S. Due to the timezone(GMT+8) and recent events in APAC, I may not reply in time. Sorry for the inconvinence.

 

Yours,

Li

0 Likes
Message 8 of 26

Anonymous
Not applicable

No worries about the response time im just glad im getting some insight. So i sincerly thank you.

 

 

im a bit confused by your response.

 

 

 

im not sure what you mean by "output fragment is no longer needed."

to me that means to do something like this

fColorShaderInstance->addInputFragment("mayaFileTexture","", "diffuseColor");

 

i do understand what you mean by float3 and the struct not matching

so i tried this 

fColorShaderInstance->addInputFragment("mayaFileTexture","defaultColor", "diffuseColor");

 

 

both of these are still returning a result of 

(kUnknownParameter): Unexpected Internal Failure

 

 

what are the attributes that im supposed to be using?

 

0 Likes
Message 9 of 26

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

I mean

static const MString sFragmentOutputName("fileTexturePluginFragmentOutput");

In original fileTexture is no longer needed.

 

 

In the rest fragments you can find

<outputs>
	<struct name=\"output\" struct_name=\"fileTexturePluginFragmentOutput\" />
</outputs>

 

That's the defination of fragment output. The original is a struct which contains float3 for RGB and float for alpha. The diffuseColor is float3, so the original struct is not suitable, you'll need to modify original shader and replace the struct with float3.

 

I think diffuseColor is bilnn color attribute, so the addInputFragment should be something like

fColorShaderInstance->addInputFragment("mayaFileTexture","output", "color");

 

Yours,

Li

0 Likes
Message 10 of 26

Anonymous
Not applicable

i see what happened i stoppped looking at the fileTextureNode example.

 

 

 

im using a fragment that already exists in the fragment manager called maya FileTexture where the xml is 

 

 

 

<fragment_graph  name="mayaFileTexture" ref="mayaFileTexture" class="FragmentGraph" version="1.0" feature_level="0" >
    <fragments>
            <fragment_ref name="mayaFileTextureOutput" ref="mayaFileTextureOutput" />
            <fragment_ref name="mayaFileTextureColorEffects" ref="mayaFileTextureColorEffects" />
            <fragment_ref name="mayaFileTextureBase" ref="mayaFileTextureBase" />
            <fragment_ref name="mayafloat2PassThrough7" ref="mayafloat2PassThrough" />
            <fragment_ref name="maya2dTextureUVOutOfBounds" ref="maya2dTextureUVOutOfBounds" />
    </fragments>
    <connections>
        <connect from="mayaFileTextureColorEffects.mayaFileTextureColorEffects" to="mayaFileTextureOutput.mayaFileTextureOutput" />
        <connect from="mayaFileTextureBase.mayaFileTextureBase" to="mayaFileTextureColorEffects.effectsIn" />
        <connect from="maya2dTextureUVOutOfBounds.maya2dTextureUVOutOfBounds" to="mayaFileTextureColorEffects.outOfBounds" />
        <connect from="mayafloat2PassThrough7.mayafloat2PassThrough" to="mayaFileTextureBase.uvCoord" />
        <connect from="maya2dTextureUVOutOfBounds.maya2dTextureUVOutOfBounds" to="mayaFileTextureBase.outOfBounds" />
        <connect from="mayafloat2PassThrough7.mayafloat2PassThrough" to="maya2dTextureUVOutOfBounds.uvCoord" />
    </connections>
    <properties>
        <float2  name="uvCoord" ref="mayafloat2PassThrough7.input" semantic="mayaUvCoordSemantic" flags="varyingInputParam" />
        <texture2  name="map" ref="mayaFileTextureBase.map" />
        <sampler  name="textureSampler" ref="mayaFileTextureBase.textureSampler" />
        <float3  name="defaultColor" ref="mayaFileTextureBase.defaultColor" />
        <bool  name="hasAlpha" ref="mayaFileTextureBase.hasAlpha" />
        <bool  name="invertV" ref="mayaFileTextureBase.invertV" />
        <float2  name="UVScale" ref="mayaFileTextureBase.UVScale" />
        <float2  name="UVOffset" ref="mayaFileTextureBase.UVOffset" />
        <bool  name="invert" ref="mayaFileTextureColorEffects.invert" />
        <bool  name="alphaIsLuminance" ref="mayaFileTextureColorEffects.alphaIsLuminance" />
        <float  name="exposure" ref="mayaFileTextureColorEffects.exposure" />
        <float3  name="colorGain" ref="mayaFileTextureColorEffects.colorGain" />
        <float3  name="colorOffset" ref="mayaFileTextureColorEffects.colorOffset" />
        <float  name="alphaGain" ref="mayaFileTextureColorEffects.alphaGain" />
        <float  name="alphaOffset" ref="mayaFileTextureColorEffects.alphaOffset" />
    </properties>
    <values>
<float3 name="defaultColor" value="0.500000,0.500000,0.500000"  />
<bool name="hasAlpha" value="false"  />
<bool name="invertV" value="true"  />
<float2 name="UVScale" value="1.000000,1.000000"  />
<float2 name="UVOffset" value="0.000000,0.000000"  />
<bool name="invert" value="false"  />
<bool name="alphaIsLuminance" value="false"  />
<float name="exposure" value="0.000000"  />
<float3 name="colorGain" value="1.000000,1.000000,1.000000"  />
<float3 name="colorOffset" value="0.000000,0.000000,0.000000"  />
<float name="alphaGain" value="1.000000"  />
<float name="alphaOffset" value="0.000000"  />
    </values>
    <outputs>
        <struct  name="mayaFileTextureOutput" ref="mayaFileTextureOutput.mayaFileTextureOutput" />
    </outputs>
</fragment_graph>

 

 

so from lloking at this i would think i would do 

fColorShaderInstance->addInputFragment("mayaFileTexture","mayaFileTextureOutput", "diffuseColor")

 

 

0 Likes
Message 11 of 26

Anonymous
Not applicable

oooohhhh ok ok ok 

 

 

i think i get it 

 

 

regardless of what i do i have to write my own custom fragment shader

 

 

in the fileTexture example 

<outputs>
	<struct name=\"output\" struct_name=\"fileTexturePluginFragmentOutput\" />
</outputs>

 this struct returns a rgb and an alpha (like you said)

 

 

 

 

still reffering to the fileTexture example found here

 

 

i would only be using the  fileTexturePluginFragment (i think)

i wouldnt be using the fragmentGraph because the connections dont need to be specified 

and the fileTexturePluginFragmentOutput defines the struct that i wouldnt be using because we need float3

 

 

the shader implementation would become this in the fileTexturePluginFragment implementations

that returns the float3 and only the float3

 

<outputs>
<float3 name=\"output\" />"
</outputs>

and the implimentation would become 

 

 

float3 fileTexturePluginFragment(float2 uv, Texture2D map, sampler mapSampler)
 uv -= floor(uv);
 uv.y = 1.0f - uv.y;
 float4 color = map.Sample(mapSampler, uv); \
 return color.rgb;
} 

 

 

 

 

and after adding this fragment to the fragment manager 

 

 

 

i would do addInputFragment("fileTexturePluginFragment", "output", "diffuseColor" )

 

 

 

please let me know if this is the right track.

 

 

 

 

0 Likes
Message 12 of 26

cheng_xi_li
Autodesk Support
Autodesk Support

Hmm,

 

Perhaps you'll still need to use fragmentGraph there instead of directly using the fileTexturePluginFragment and the diffuseColor attribute of blinn should be "color".

 

Other than that, I think you are on the right track:)

 

Yours,

Li

0 Likes
Message 13 of 26

Anonymous
Not applicable
Ok i will attempt to implement this tomorrow. It's 3am by me

--
Sent from Gmail Mobile
0 Likes
Message 14 of 26

Anonymous
Not applicable

this is the fragment shader i created.

 

when i go into texture mode the geometry turns transparent

and nothing shows

 

the fragment gets added sucessfully.

 

please keep in my that im using a new shaderInstace of mayaSurfaceShaderSurface

 

 

applying like this

 

           fColorShaderInstance = shaderMgr->getFragmentShader("mayaSurfaceShaderSurface","outColor" , true);

 

my fragment file is as follows

 

 

 

<fragment uiName="fileTexturePluginFragment" name="fileTexturePluginFragment" type="plumbing" class="ShadeFragment" version="1.0">
    <description><![CDATA[Simple file texture fragment]]></description>
    <properties>
        <float2 name="uvCoord" semantic="mayaUvCoordSemantic" flags="varyingInputParam"/>
        <texture2 name="map"/>
        <sampler name="textureSampler"/>
    </properties>
    <values>
    </values>
    <outputs>
        <float3 name="output"/>
    </outputs>
    <implementation>
        <implementation render="OGSRenderer" language="Cg" lang_version="2.100000">
            <function_name val="fileTexturePluginFragment"/>
            <source><![CDATA[
            float3 fileTexturePluginFragment(float2 uv, texture2D map, sampler2D mapSampler)
            {
                uv -= floor(uv);
                uv.y = 1.0f - uv.y;
                float4 color = tex2D(mapSampler, uv);
                return color.rgb;
            } ]]>
            </source>
        </implementation>
        <implementation render="OGSRenderer" language="HLSL" lang_version="11.000000">
            <function_name val="fileTexturePluginFragment"/>
            <source><![CDATA[
            float3 fileTexturePluginFragment(float2 uv, Texture2D map, sampler mapSampler)
            {
                uv -= floor(uv);
                uv.y = 1.0f - uv.y;
                float4 color = map.Sample(mapSampler, uv);
                return color.rgb;
            } ]]>
            </source>
        </implementation>

        <implementation render="OGSRenderer" language="GLSL" lang_version="3.0">
            <function_name val="fileTexturePluginFragment"/>
            <source><![CDATA[
            vec3 fileTexturePluginFragment(vec2 uv, sampler2D mapSampler)
            {
                uv -= floor(uv);
                uv.y = 1.0f - uv.y;
                vec4 color = texture(mapSampler, uv); \n
                return color.rgb;
            }]]>
            </source>
        </implementation>
    </implementation>
</fragment>

 

 

which gets assigned with this

 

 

 

CHECK_MSTATUS(fColorShaderInstance->addInputFragment("fileTexturePluginFragment","output", "outColor"));

 

 

 

i use this to set the parameters

 

 

 

 

MHWRender::MSamplerStateDesc desc;
                        desc.filter = MHWRender::MSamplerState::kAnisotropic;
                        desc.maxAnisotropy = 16;
                        const MHWRender::MSamplerState *fSamplerState = MHWRender::MStateManager::acquireSamplerState(desc);

                        if (fSamplerState)
                        {
                            CHECK_MSTATUS(fColorShaderInstance->setParameter("textureSampler", *fSamplerState));
                        }

//                        fColorShaderInstance->setParameter("diffuse", &fDiffuse[0]);
                        CHECK_MSTATUS(fColorShaderInstance->setParameter("map", mColorTexture));

 

 

 

 

0 Likes
Message 15 of 26

Anonymous
Not applicable

this is the fragment shader i created.
 
when i go into texture mode the geometry turns transparent
and nothing shows
 
the fragment gets added sucessfully.
 
please keep in my that im using a new shaderInstace of mayaSurfaceShaderSurface
 
 
applying like this

 

 

fColorShaderInstance = shaderMgr->getFragmentShader("mayaSurfaceShaderSurface","outColor" , true);

 

 

my fragment file is as follows

 

 

 

<fragment uiName="fileTexturePluginFragment" name="fileTexturePluginFragment" type="plumbing" class="ShadeFragment" version="1.0">
    <description><![CDATA[Simple file texture fragment]]></description>
    <properties>
        <float2 name="uvCoord" semantic="mayaUvCoordSemantic" flags="varyingInputParam"/>
        <texture2 name="map"/>
        <sampler name="textureSampler"/>
    </properties>
    <values>
    </values>
    <outputs>
        <float3 name="output"/>
    </outputs>
    <implementation>
        <implementation render="OGSRenderer" language="Cg" lang_version="2.100000">
            <function_name val="fileTexturePluginFragment"/>
            <source><![CDATA[
            float3 fileTexturePluginFragment(float2 uv, texture2D map, sampler2D mapSampler)
            {
                uv -= floor(uv);
                uv.y = 1.0f - uv.y;
                float4 color = tex2D(mapSampler, uv);
                return color.rgb;
            } ]]>
            </source>
        </implementation>
        <implementation render="OGSRenderer" language="HLSL" lang_version="11.000000">
            <function_name val="fileTexturePluginFragment"/>
            <source><![CDATA[
            float3 fileTexturePluginFragment(float2 uv, Texture2D map, sampler mapSampler)
            {
                uv -= floor(uv);
                uv.y = 1.0f - uv.y;
                float4 color = map.Sample(mapSampler, uv);
                return color.rgb;
            } ]]>
            </source>
        </implementation>

        <implementation render="OGSRenderer" language="GLSL" lang_version="3.0">
            <function_name val="fileTexturePluginFragment"/>
            <source><![CDATA[
            vec3 fileTexturePluginFragment(vec2 uv, sampler2D mapSampler)
            {
                uv -= floor(uv);
                uv.y = 1.0f - uv.y;
                vec4 color = texture(mapSampler, uv); \n
                return color.rgb;
            }]]>
            </source>
        </implementation>
    </implementation>
</fragment>

 

which gets assigned with this

 

 

CHECK_MSTATUS(fColorShaderInstance->addInputFragment("fileTexturePluginFragment","output", "outColor"));

 

 

 

i use this to set the parameters

 

MHWRender::MSamplerStateDesc desc;
                        desc.filter = MHWRender::MSamplerState::kAnisotropic;
                        desc.maxAnisotropy = 16;
                        const MHWRender::MSamplerState *fSamplerState = MHWRender::MStateManager::acquireSamplerState(desc);

                        if (fSamplerState)
                        {
                            CHECK_MSTATUS(fColorShaderInstance->setParameter("textureSampler", *fSamplerState));
                        }

//                        fColorShaderInstance->setParameter("diffuse", &fDiffuse[0]);
                        CHECK_MSTATUS(fColorShaderInstance->setParameter("map", mColorTexture));
0 Likes
Message 16 of 26

cheng_xi_li
Autodesk Support
Autodesk Support
Accepted solution

Hi cronicryo,

 

Sorry for the late reply, and I think I made some mistakes earlier.

 

I tried to modify the vp2BlinnShader along with fileTexture in our devkit. It can use a texture from file now. There is still a problem with swatch display, I'll simply remove it for now.

 

To make vp2BlinnShader display a texture from a file. 

 

I created a shader fragment as I mentioned before, but the diffuseColor should be float4 instead of float3. And the diffuseColor property should be diffuseColor instead of color.

 

void initializeFragmentShaders()
		{

			static const MString sFragmentName("fileTexturePluginFragment");
			static const char* sFragmentBody =
				"<fragment uiName=\"fileTexturePluginFragment\" name=\"fileTexturePluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">"
				"	<description><![CDATA[Simple file texture fragment]]></description>"
				"	<properties>"
				"		<float2 name=\"uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" />"
				"		<texture2 name=\"map\" />"
				"		<sampler name=\"textureSampler\" />"
				"	</properties>"
				"	<values>"
				"	</values>"
				"	<outputs>"
				"		<float4 name=\"output\" />"
				"	</outputs>"
				"	<implementation>"
				"	<implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.100000\">"
				"		<function_name val=\"fileTexturePluginFragment\" />"
				"		<source><![CDATA["
				"float4 fileTexturePluginFragment(float2 uv, texture2D map, sampler2D mapSampler) \n"
				"{ \n"
				"	uv -= floor(uv); \n"
				"	uv.y = 1.0f - uv.y; \n"
				"	float4 color = tex2D(mapSampler, uv); \n"
				"	return color.rgba; \n"
				"} \n]]>"
				"		</source>"
				"	</implementation>"
				"	<implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.000000\">"
				"		<function_name val=\"fileTexturePluginFragment\" />"
				"		<source><![CDATA["
				"float4 fileTexturePluginFragment(float2 uv, Texture2D map, sampler mapSampler) \n"
				"{ \n"
				"	uv -= floor(uv); \n"
				"	uv.y = 1.0f - uv.y; \n"
				"	float4 color = map.Sample(mapSampler, uv); \n"
				"	return color.rgba; \n"
				"} \n]]>"
				"		</source>"
				"	</implementation>"
				"	<implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">"
				"		<function_name val=\"fileTexturePluginFragment\" />"
				"		<source><![CDATA["
				"float4 fileTexturePluginFragment(vec2 uv, sampler2D mapSampler) \n"
				"{ \n"
				"	uv -= floor(uv); \n"
				"	uv.y = 1.0f - uv.y; \n"
				"	vec4 color = texture(mapSampler, uv); \n"
				"	return color.rgba; \n"
				"} \n]]>"
				"		</source>"
				"	</implementation>"
				"	</implementation>"
				"</fragment>";
			// Register fragments with the manager if needed
			//
			MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();
			if (theRenderer)
			{
				MHWRender::MFragmentManager* fragmentMgr =
					theRenderer->getFragmentManager();
				if (fragmentMgr)
				{
					// Add fragments if needed
					bool fragAdded = fragmentMgr->hasFragment(sFragmentName);					
					if (!fragAdded)
					{
						fragAdded = (sFragmentName == fragmentMgr->addShadeFragmentFromBuffer(sFragmentBody, false));
					}				
					if (fragAdded)
					{
						fFragmentName = sFragmentName;
						TRACE_API_CALLS("Added Fragment");
					}
				}
			}
		}

void createCustomMappings()
{
// Set up some mappings for the parameters on the file texture fragment,
// there is no correspondence to attributes on the node for the texture
// parameters.
MHWRender::MAttributeParameterMapping mapMapping(
"map", "", false, true);
mappings.append(mapMapping);

MHWRender::MAttributeParameterMapping textureSamplerMapping(
"textureSampler", "", false, true);
mappings.append(textureSamplerMapping);
}

And I called them in the createShaderInstance

void createShaderInstance()
	{
		TRACE_API_CALLS("vp2BlinnShaderOverride::createShaderInstance");
		MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
		const MHWRender::MShaderManager* shaderMgr = renderer ? renderer->getShaderManager() : NULL;
		if (!shaderMgr)
			return;

		initializeFragmentShaders();		
		createCustomMappings();

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

Then, I modified updateShaderInstance,

	void updateShaderInstance()
	{
		TRACE_API_CALLS("vp2BlinnShaderOverride::updateShaderInstance");
		if (fColorShaderInstance)
		{
			// Update shader to mark it as drawing with transparency or not.
			fColorShaderInstance->setIsTransparent( isTransparent() );

			//Replace diffuse update with fragment parameters update
			//fColorShaderInstance->setParameter("diffuseColor", &fDiffuse[0] );
			updateShader();
			fColorShaderInstance->setParameter("specularColor", &fSpecular[0] );
		}
		if (fNonTexturedColorShaderInstance)
		{
			fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
		}
	}

void updateShader()
		{
			TRACE_API_CALLS("Update texture");
			MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
			
			fFragmentTextureShader = fColorShaderInstance;
			if(!fFragmentTextureShader)
			{
				TRACE_API_CALLS("Can't get fragment texture");
				return;
			}
			// A random png file on my disk
			MString fFileName("D:\\screenshot.png");

			if (fResolvedMapName.length() == 0)
			{

				const MHWRender::MAttributeParameterMapping* mapping =
					mappings.findByParameterName("map");
				if (mapping)
				{
					TRACE_API_CALLS("Resolved mapping parameter");

					fResolvedMapName = mapping->resolvedParameterName();
				}
			}
			if (fResolvedSamplerName.length() == 0)
			{
				const MHWRender::MAttributeParameterMapping* mapping =
					mappings.findByParameterName("textureSampler");
				if (mapping)
				{
					TRACE_API_CALLS("Resolved texture sampler");
					fResolvedSamplerName = mapping->resolvedParameterName();
				}
			}

			// Set the parameters on the shader
			if (fResolvedMapName.length() > 0 && fResolvedSamplerName.length() > 0)
			{
				// Set sampler to linear-wrap
				if (!fSamplerState)
				{
					MHWRender::MSamplerStateDesc desc;
					desc.filter = MHWRender::MSamplerState::kAnisotropic;
					desc.maxAnisotropy = 16;
					fSamplerState = MHWRender::MStateManager::acquireSamplerState(desc);
				}
				if (fSamplerState)
				{
					TRACE_API_CALLS("Update sampler parameter");
					fFragmentTextureShader->setParameter(fResolvedSamplerName, *fSamplerState);
				}

				// Set texture
				MHWRender::MRenderer* renderer = MHWRender::MRenderer::theRenderer();
				if (renderer)
				{
					MHWRender::MTextureManager* textureManager =
						renderer->getTextureManager();
					if (textureManager)
					{
						MHWRender::MTexture* texture =
							textureManager->acquireTexture(fFileName);
						if (texture)
						{
							MHWRender::MTextureAssignment textureAssignment;
							textureAssignment.texture = texture;
							TRACE_API_CALLS("Update texture parameter");

							fFragmentTextureShader->setParameter(fResolvedMapName, textureAssignment);

							// release our reference now that it is set on the shader
							textureManager->releaseTexture(texture);
						}
					}
				}
			}
		}

 

At last, we need to add geometry texture to the shader since we can't update UV directly. Add following codes in the initialize

 

                MHWRender::MVertexBufferDescriptor textureDesc(
			empty, // Better to have a name here
			MHWRender::MGeometry::kTexture,
			MHWRender::MGeometry::kFloat,
			2);
		addGeometryRequirement(textureDesc);

It should be working now.

0 Likes
Message 17 of 26

Anonymous
Not applicable

i did get this to work in your absensce i was missing the 

 

 MHWRender::MVertexBufferDescriptor textureDesc(
			empty, // Better to have a name here
			MHWRender::MGeometry::kTexture,
			MHWRender::MGeometry::kFloat,
			2);
		addGeometryRequirement(textureDesc);

 

which took me a bit to figure out the next thing i ran into was getting the diffuse color to show up because the texture was connected to diffuseColor it wasnt showin up so i had to had more parameters to make a switch for the returned value


so my fragment function looks like this generally 

 

 

            <source><![CDATA[
            float3 fileTexturePluginFragment(float3 myColor, bool useTexture, float2 uv, texture2D map, sampler2D mapSampler)
            {
                if(useTexture){
                    float4 color = tex2D(mapSampler, uv);
                    return color.rgb;
                }else{
                    return myColor;
                }

            } ]]>
            </source>
0 Likes
Message 18 of 26

Anonymous
Not applicable

Hi,

I am trying to do almost the same thing, except I try to achieve this with a MPxSubSceneOverride and not a MPxSurfaceShadingNodeOverride.

The main problem is that the MPxSubSceneOverride doesn't have a getCustomMappings function and I cannot reach the MHWRender::MAttributeParameterMappingList so I cannot map the sampler's and the map's attributes.

Is there any way to do this kind of fragment connection between a surface shader and a file texture shader in a MPxSubSceneOverride?

 

Thanks,

Ferenc

0 Likes
Message 19 of 26

cheng_xi_li
Autodesk Support
Autodesk Support

Hi ferenc,

 

You can use MShaderInstance::parameterList and MShaderInstance::parameterType to get shader's parameter. 

 

Sampler should be named as smap for Maya default's shader(k3dSolidTexture).

 

Yours,

Li

0 Likes
Message 20 of 26

Anonymous
Not applicable

Hi Li,

Unfortunately something wrong here. I am posting the relevant code here, can you check it? I used MShaderInstance::parameterList to get the parameters, so I created a sampler just like ina shader node, but nothing is drawn in the viewport.

If I use only a solidShader and I set it's color, it works fine.

 

if (!fShadedShader)
{
	if (!fSamplerState)
	{
		MHWRender::MSamplerStateDesc desc;
		desc.filter = MHWRender::MSamplerState::kAnisotropic;
		desc.maxAnisotropy = 16;
		fSamplerState = MHWRender::MStateManager::acquireSamplerState(desc, &status);
	}
	
	fShadedShader = shaderMgr->getStockShader(MHWRender::MShaderManager::k3dSolidTextureShader);
	if (fSamplerState)
	{
		fShadedShader->setParameter("samp", *fSamplerState);
	}
	MHWRender::MTextureManager* textureManager =
		renderer->getTextureManager();
	if (textureManager)
	{
		MString fFileName;
		MRenderUtil::exactFileTextureName("C:/image.hdr", false, "", fFileName);
		MHWRender::MTexture* texture =
			textureManager->acquireTexture(fFileName);
		if (texture)
		{
			MHWRender::MTextureAssignment textureAssignment;
			textureAssignment.texture = texture;
			fShadedShader->setParameter("map", textureAssignment);
			textureManager->releaseTexture(texture);
		}
	}
}

Thanks,

Ferenc

0 Likes