Tuesday, May 17, 2016

Wednesday, April 6, 2016

When working in a larger group or company it can be useful to share nodes.
Not just share them, but also be able to share updates to shader networks more easily.

For example technical artists or programmers may want to make a set of shading nodes that artists can use that match with their game engine.

ShaderFX has this build into its group-nodes.

Here is an example of how to create your own custom shader nodes for your company and share them over the network with your team members.

With Maya closed, you can add a user variable to your system variables:

SHADERFX_CUSTOMGROUPPATH\\autodesk.com/game_title_group_nodes/

With this set, the next time you start up Maya, it will now pull its custom group nodes from this network folder.

(Note that I believe we added this system environment variable somewhere in 2016, but I cannot remember what extension)

Now lets build a set of custom nodes.
We will use the Custom Code node, since it allows technical artists and programmers to enter their own code more quickly instead of using lots of complicated shader graphs.

Enable "Advanced Mode" in shaderfx.
Add a custom code node.
Customize its code by selecting it and pressing "Edit".
(Here we just input and output a color, but please see the Maya help for more details on the Custom Code node)

Select the node and use "Create Group"

Select the left node of the group
Supply Class, Category and Sub menu name for the group.
Press Group / Save Group

This will save the node into your network path you provided for SHADERFX_CUSTOMGROUPPATH

If all went well, it will now show the new group node in the right-click menu:

Add it to the scene and connect any inputs it needs.
Save your Maya scene and close Maya.

Re-open Maya (could even open it on a team-members machine)
Create the Group node you created.
Open it and make some changes to it.

NOTE: make sure you create a valid node. If you break the node, your original Maya scene will give a shading error.

Save the edited group.
Re-open the Maya scene you saved previously.

Notice that now the scene has been updated to use your new node.
(See the new input we added and the object is now purple)

Wednesday, March 23, 2016

Some times you want to use the same shader graph for a bunch of different nodes, but have slightly different parameters for each of the objects used.

A deeper discussion can be found on various Renderman help pages (e.g. https://renderman.pixar.com/view/how-to-primitive-variables)

A similar concept exists in Maya DG nodes called TripleSwitch.

In ShaderFX, we can do this using the Primitive Variable node for float values, or the TextureMap node for textures (string attributes).

You start by adding a custom attribute onto your Maya Shape node.
Note that it is important the attribute ends up on the Shape and not on the transform node or any other node.
So make sure you select the shape node before adding the custom attribute.

The name you use for the custom attribute, is the name we are also going to use on the "Primitive Variable" node inside ShaderFX.

(You have to switch ShaderfX into "Advanced Mode" to find the Primitive Variable node)

Now that we have the custom attribute on the shape node and we have added a shaderFX shader to the object and changed its graph to contain the Primitive Variable node, we can change the value of the custom attribute for each shape.

The quirky part is that this does not update "live" and does not support animation directly via the custom attribute.

So to see the update of the custom attribute into the shader, you use one of two methods:

Open ShaderFX and use Tools / Compute Graph to update the value.

Use MEL command: shaderfx -sfxnode "ShaderfxShader1" -update;

Knowing this limitation, you can see it is mostly there to allow some custom floats or textures to replace parts of the shader graph per object. It is not meant to completely replace regular Maya attribute that get put into the shader.

However, you can get pretty creative.

For example, lets say you want to animate between 5 different colors between 100 objects.

You can add 5 "color nodes" in the shaderfx graph and lerp (or if-statement switch) between them based on the primitive variable value found on the shape node.

This means you no longer have to worry about animating or updating the shape node attribute constantly. The primitive variable becomes more a "node id" that you can use to take different shading paths in the shader graph.

Saturday, March 28, 2015

Somebody asked me how to unwrap the rendered result of a shaderfx shader to a texture.
This may seem like a strange request, because why would you want to bake your lighting into your texture?

But I have actually had to do this myself once when porting a xbox 360 game over to low-end mobile devices.
We were a very small team and could not redo all assets and we really only wanted a single texture per asset.

So, here is how to do the shaderfx part of it.
Lets say we want to unwrap a rendered texture for this horse model:

What we need to do is go into Advanced mode, then enter into the "Material grp".
Add a new "Vertex Shader UV space" group node.
Replace ALL (!) the output of the existing Vertex Shader grp with this new node.

It will then unwrap the 3d model in your 3d view.
From here, you could use other tools to grab the view result and save it as an image.

Important:
If you want to save this file with the model unwrapped in the screen, you have to save a NEW grp for the Material grp you just changed. Otherwise, your changes won't stick after re-opening the file.
You can save the grp by renaming its Class property to something unique and then using "Save Grp".

(One tip might be to make the Maya viewport black before saving the image, or if you need to create a mask, make it bright purple so it is easy to select the background color in something like Photoshop)

Friday, October 4, 2013

Using Transparency from textures or float values in ShaderFX is pretty easy, but you need to know to enable one or two settings on the Base Material node for it to work.

You connect your transparency value to the opacity socket on the Surface Shader (top).
Then enable the Opacity checkbox on the Base Material node.

UPDATE: in new versions of Maya/ShaderFX you no longer have to enable the Opacity checkbox. Simply plugging something into the opacity input will make the material transparent

You likely also want to disable the "Depth Write" checkbox so that transparent object do not block the rendering of objects behind them.

By default objects render double sided in the Maya view, if you do not want this, disable the "Double Sided" checkbox on the Shape node of the object.

You should get reasonable results, but keep in mind that Maya's viewport is not a game engine and so sometimes sorting is not perfect. There are some improvements you can get by switching to "Depth Peeling" transparency algorithm. This can be found in the Viewport 2.0 settings dialog.

Unfortunately in Maya LT this crashes, but I believe this will be fixed in SP 1.

Even with Depth Peeling things are not always sorting great. Hopefully we can improve this in the future.

Saturday, September 28, 2013

Sometimes when working with groups you end up with a few empty sockets inside the group and there is no button to remove these empty sockets (we may eventually add one).

But there is a way to get rid of them.

Empty sockets are removed during saving/Loading (saving and then loading the group or the scene).

So when you reload the group/scene the empty sockets will be gone, if the following conditions are met:

1. The label of the socket is empty (so it displays "any" as its label in the view)

2. There are no used sockets below it.

3. It is not the only empty socket (we always keep one empty socket)

Number 1 and 2 are are probably not that obvious, but the reason for it was if the user is in the middle of creating groups and saves a scene and goes home for the day, you don't want to loose your work and have to redo labeling or organizing your sockets.

In order to ensure a socket gets removed, you have to use the "Move Socket Up" button on any used sockets below it. (Which can also be a bit tedious to use at times, but it is what we have right now)

Here is the corrected group for which the unused sockets will get removed after save/load.

(Except for 1 'any' socket since we always keep one for users to add new connections)

Thursday, September 19, 2013

Some times you may want to sample a single texture with different settings, such as different UVs.

You can of course place down multiple "Texture Map" nodes and point them all to the same texture.

Then connect different UVs into each.

This works ok, but becomes a problem when you want to expose the texture path to the Attribute Editor as a parameter for artists to set when the node graph is closed. You really want the artist to only have to supply the path to the texture once.

When using Texture Map nodes, each would need to be visible to the AE in order for the path to be set. It would be strange for the artist to have to set the same texture in the shader multiple times. We can resolve this by constructing the sampling with your own set of nodes instead of using the Texture Map node.

To see these nodes, you should switch to "Advanced Mode" in the right-click menu.

You can look inside the Texture Map node for reference.

Here is an image with some explanation of how you can set this up:

The above example assumes you are using a regular 2D texture.

If you want to use a Cube texture, then you must also add a "Texture Type" node, set it to Cube and input it into each of the four nodes in the picture.

Friday, September 6, 2013

** NOTE: we ship a more up to date version of this node with Maya that works with the new Maya Core Profile. I recommend you use it instead of the older version linked above **

I tried to stay true to the original shader code as much as possible.

To do that, I used a Custom Code node inside ShaderFX to paste Valve's original CGFX code into.

Then I decided to remove any CGFX specific semantics from the Shader.

By doing that, you can freely switch between OpenGL and DirectX11 with the same Maya LT scene and ShaderFX graph.

The only function I had to replace was a few calls to Tex2D().

I made those Tex2D calls "inputs" into the Custom Code node function and used the ShaderFX "Texture Map" node instead, which will automatically switch correctly between OpenGL and DX11.

It was about a day work to switch the code from the CGFX file over to a ShaderFX graph.

I had never seen the shader code before, so it took some time figuring out how it worked, but of course I had the benefit of knowing ShaderFX very well.

Another change I made was to add support for real-time shadows and point/spot/direction lights.

This was very easy, because I could re-use the "Light Contribution" group node in ShaderFX, which does all the magic for us.

I maintained the 1-light support for the shader.

Adding more lights would be easy, just bump up the "number of lights" property in the shader.

But the way I have structure the shader code in the custom code node, adding extra lights would mean we are not a very efficient shader anymore because every texture sample and calculation would be re-done inside the light loop.

For example, sampling the normal map texture would happen for every light!

Pretty waste full, but it can be fixed fairly easily if somebody wants to add extra lights.

It can be resolved by splitting the light dependent calculations and the rest of the calculations from the Custom Code node into two Custom Code nodes. Then use the "Inside Loop" and "After Loop" inputs on the "Socket Combiner" node. But my goal was to just reproduce as close as possible the original shader, so I did not do that work.

I love the graphics of Valve's DOTA2, it is a fantastic game. And seeing the models like this in Maya LT is quite rewarding. :)

The attribute on the locator drives the value in the shader.
In ShaderFX "Values nodes" (such as floats, colors, textures) have an option called "Input from Maya". When you enable this option, the value is exposed as a regular Maya Attribute in the dependency graph and can be connected to your rig:Download Wrinkle Map ShaderFX graph