日別アーカイブ: 2014年4月23日

Maya 2015 ShaderFX のノード情報を読みだしてみる

ShaderFX は Plugin で実現されており、shaderfx コマンドを介して情報にアクセスできます。
内部の Node 構造は予想以上に複雑で、初期状態のデフォルトでも 1244個。
普段は Group 化されているため表に出てきませんが、
Group をすべて展開していくとこれだけの数になるようです。

以下、すべて読みだしてみるスクリプト。

// mel
global proc a7ListShaderFx()
{
    string  $node_name= "ShaderfxShader1"; // 展開する Node 名


    int $count= `shaderfx -sfxnode $node_name -getNodeCount`;
    int $root= `shaderfx -sfxnode $node_name -getHwShaderNodeRootGrpID`;
    int $hwnode= `shaderfx -sfxnode $node_name -getHwShaderNodeID`;
    print ( "count=" + $count + "\n" );
    print ( "root=" + $root + "\n" );
    print ( "hwnode=" + $hwnode + "\n" );

    string  $indent= "";
    int $ni;
    for( $ni= 0 ; $ni< $count ; $ni++ ){
        int $uid= `shaderfx -sfxnode $node_name -getNodeUIDFromIndex $ni`;
        string  $class_name= `shaderfx -sfxnode $node_name -getNodeClassName $uid`;
        string  $name= `shaderfx -sfxnode $node_name -getPropertyValue $uid "name"`;
        string  $flag= "";
        if( `shaderfx -sfxnode $node_name -isGroupStart $uid` ){
            int $gend_uid= `shaderfx -sfxnode $node_name -getGroupEndUID $uid`;
            $flag+= "* Group START from " + $uid + " to " + $gend_uid;
            print "group start {\n";
            $indent= "  ";
        }
        if( `shaderfx -sfxnode $node_name -isGroupEnd $uid` ){
            $flag+= "* Group END";
        }
        if( `shaderfx -sfxnode $node_name -isGroupFromDisk $uid` ){
            int $value= `shaderfx -sfxnode $node_name -isGroupFromDisk $uid`;
            $flag+= "* Group FROM DISK (" + $value + ")";
        }
        print ( $indent + $uid + ": <" + $class_name + "> " + $name + " " + $flag +  "\n" );

        // Properties
        string  $prop_list[]= `shaderfx -sfxnode $node_name -listProperties $uid`;
        for( $prop_name in $prop_list ){
            string  $prop_type= `shaderfx -sfxnode $node_name -getPropertyType $uid $prop_name`;
            switch( $prop_type ){
            case "float4":
                print ( $indent + "  " + $prop_name + " <" + $prop_type + ">=   skip...\n" );
                break;
            case "stringlist": {
                    string  $prop_value[]= `shaderfx -sfxnode $node_name -getPropertyValue $uid $prop_name`;
                    print ( $indent + "  " + $prop_name + " <" + $prop_type + ">=\n" );
                    for( $si in $prop_value ){
                        print ( $indent + "     [" + $si + "]\n" );
                    }
                }
                break;
            default: {
                    string  $prop_value= `shaderfx -sfxnode $node_name -getPropertyValue $uid $prop_name`;
                    print ( $indent + "  " + $prop_name + " <" + $prop_type + ">= [" + $prop_value + "]\n" );
                }
                break;
            }
        }

        // Sockets
        int $socket_type;
        for( $socket_type= 0 ; $socket_type < 2 ; $socket_type++ ){
            int $socket_count= `shaderfx -sfxnode $node_name -getSocketCount $uid $socket_type`;
            int $si;
            if( $socket_count != 0 ){
                switch( $socket_type ){
                case 0: print ( $indent + "  ** input socket\n" ); break;
                case 1: print ( $indent + "  ** output socket\n" ); break;
                }
            }
            for( $si= 0 ; $si < $socket_count ; $si++ ){
                string $socket_name= `shaderfx -sfxnode $node_name -getSocketName $uid $socket_type $si`;
                string $socket_stype= `shaderfx -sfxnode $node_name -getSocketType $uid $socket_type $si`;
                int $connected_count= `shaderfx -sfxnode $node_name -getConnectedSocketCount $uid $socket_type $si`;
                print ( $indent + "    socket("+ $si + "): " + $socket_name + " <" + $socket_stype + "> c:" + $connected_count + "\n" );
                int $ci;
                for( $ci= 0 ; $ci < $connected_count ; $ci++ ){
                    string $connected_node= `shaderfx -sfxnode $node_name -getConnectedNodeID $uid $socket_type $si $ci false`;
                    string $connected_id= `shaderfx -sfxnode $node_name -getConnectedSocketIndex $uid $socket_type $si $ci false`;
                    print ( $indent + "      connected: uid=" + $connected_node + "  socket(" + $connected_id + ")\n" );
                }
            }
        }

        if( `shaderfx -sfxnode $node_name -isGroupEnd $uid` ){
            $indent= "";
            print "}\n";
        }
    }
}

HLSL/GLSL 等のシェーダー命令を 1つ 1つ Node 化しているようなイメージです。

関連エントリ
Maya 2014 の Output Window と stderr
Maya ShaderFX