Writing a Phenomenon for Softimage XSI and Mental Ray

July 2nd, 2006 by Stefano Jannuzzo - Viewed 49847 times -




Have you ever used Apple’s Shake? Have you ever built macros with Shake? Have you ever wished you could create macros in XSI’s Render Tree?

Well you can, these are called Phenomenon. A Phenomenon is group of shaders exposed to the users as a single entity. You can hide or show, as you see fit, any parameter of the enclosed shaders making a Phenomenon a very powerful tool for sharing shader recipes or building tools for larger productions.

The advantages are:

  1. Have a more compact and readable rendertree.
  2. Allow for only a set of significant parameters to be tuned by the artist.

Let’s see how it is possible to make up a phenomenon starting from a basic rendertree.

The Goal

The following network returns red if the x coordinate of the point is lower than 1, blue elsewhere. The picture should be quite self-explanatory:

Initial Shader Tree

In this case study we want to make a new node enclosing the four primary shaders of the tree, and exposing only three parameters: the two colors and the “threshold” value.

Creating Our SPDL

We need to create a spdl file, which will be later registered.

For those who want a bit of a primer, a SPDL file is a file that defines how XSI will display a certain PPG or Shader. Check the wiki page on SPDL for more info.

The first part of the file contains a header and the declaration of the parameters we want to expose. All the guids must be randomly generated, except the one identifing the output (color) parameter.

SPDL
Version = "2.0.0.0";
Reference = "{19671971-1008-0000-8410-6A45FDB990DD}";
PropertySet "PhenoTest_params"
{
    Parameter "out" output
    {
        title = "PhenoTest";
        guid = "{4C6879FF-7EC8-11D0-8E3B-00A0C90640EC}";
        type = color;
    }
    Parameter "threshold" input
    {
        guid  = "{19671971-1008-0002-8410-6A45FDB990DD}";
        type  = scalar;
        value = 1.0;
        texturable = on;
    }
    Parameter "color1" input
    {
        guid = "{19671971-1010-0001-8410-6A45FDB990DD}";
        type = color;
        value = 1.0 0.0 0.0 1.0;
        texturable = on;
    }
    Parameter "color2" input
    {
        guid = "{19671971-1011-0001-8410-6A45FDB990DD}";
        type = color;
        value = 0.0 0.0 1.0 1.0;
        texturable = on;
    }
}

The bottom part is also quite standard. It just defines the parameter’s defaults and their position in the layout.

BEGIN "{24810490-56FF-11d2-BF23-00A0C982CE5D}"

Defaults
{
    threshold
    {
        Name = "Threshold";
        UIRange = -10.0 to 10.0 by 0.01;
    }
    color1
    {
        Name = "Color 1";
        UIType = "rgba",4;
        Commands = "{F5C75F11-2F05-11d3-AA95-00AA0068D2C0}";
    }
    color2
    {
        Name = "Color 2";
        UIType = "rgba",4;
        Commands = "{F5C75F11-2F05-11d3-AA95-00AA0068D2C0}";
    }
}

Layout "Default"
{
    Name;
    threshold;
    color1;
    color2;
}

Logic
{
}
END

What interests us is the middle section, where you hardcode the connections between shaders. This is, in essence, the part of the SPDL where you create your mini Render Tree.

MetaShader "PhenoTest_declare"
{
    Name = "PhenoTest";
    Type = texture;
    Renderer "mental ray"
    {
        Name = "PhenoTest";

        BeginText

        Node "vector_state"      = guid "{BDE291C7-077A-11D2-8A1A-00A0C9892542}";
        Node "vector_2_scalar"   = guid "{A4F08C3F-AA3A-11D2-AFD4-00A024191B9D}";
        Node "scalar_math_logic" = guid "{4D9E6800-AC2F-11D3-AE56-00A0C96E63E1}";
        Node "boolean_switch"    = guid "{85C16046-BCFA-11D1-90E9-0000F804EB21}";

        Connection "vector_state::mode"	    = value 2;

        Connection "vector_2_scalar::input"     = "vector_state";
        Connection "vector_2_scalar::component" = value 0;

        Connection "scalar_math_logic::input1"  = "vector_2_scalar";
        Connection "scalar_math_logic::input2"  = interface "threshold";
        Connection "scalar_math_logic::op"      = value 2;

        Connection "boolean_switch::input1"     = interface "color1";
        Connection "boolean_switch::input2"     = interface "color2";
        Connection "boolean_switch::switch"     = "scalar_math_logic";

        Connection root                         = "boolean_switch";

        EndText
    }
}

Aching for more details? Read on…

Pages: 1 2

13 Responses to “Writing a Phenomenon for Softimage XSI and Mental Ray”

  1. Luc-Eric says:

    This article looks ok on FireFox, but in Internet Explorer the large bitmaps aren”t being shrunk and the pagef formatting falls apart

  2. Luc-Eric, can you tell me if things are looking better? I think I may have fixed things but running IE7.0 I couldn”t see the issue to start with.

    Thanks,

  3. Luc-Eric says:

    yes it”s ok now

  4. Steven Caron says:

    is there any speed increase when rendering 1 phenomenon versus its many parts?

  5. Stefano Jannuzzo says:

    No, no speed change at all

  6. Patrick Piché says:

    Is it possible to find Shaders GUID by scripting. Exemble, selecting a shader in XSI Explorer, running a script and tell what is the GUID of this Shader?

  7. I don’t think, but I can’t be sure. However, as said, if you edit the shader spdl in the script editor (RMB + “Edit”) you have it there, after the “Reference” keyword

  8. Clyde says:

    Hi man! Your site is cool! Visit my sites, please:

  9. Eddie says:

    Amazing artwork! This is spectacularly done! Visit my sites, please:

  10. Sylvain says:

    Patrick, I think this is what the XSIUtils.DataRepository.GetIdentifier() method does, with siObjectCLSID as second parameter.
    For example:
    LogMessage( “GUID = ” + XSIUtils.DataRepository.GetIdentifier( Selection.Item(0), siObjectCLSID ) );

  11. Patrick Piché says:

    Thanks Sylvain. It’s a good start, I’m looking in a way to build those Phenomenon by script after building them in the Render Tree.

  12. [...] is an example of how sometimes you can write a phenomenon just to downgrade a more powerful node to get what you [...]