スクリプトを書いていてですね、オブジェクトにマテリアルを割り当てるために、AddMaterial メソッド を使ったんですね。 そしたらですね、異様に遅いんですよ。実行が。 マテリアル1つ与えるのに、2秒か3秒くらい待たされるんですね。 ほら。
コンスタントシェーダ1個くれてやるのに、1.828秒 もかかっています。 10回ループさせると、 やっぱり18秒とかかかりますね。 遅い。これでは困る。 普通にインターフェース上から Get > Material > Constant を実行したときは、一瞬で終わります。またもやオブジェクトモデルにすると遅くなるパターンなのだろうか・・・と思ったんですが、ApplyShader コマンドを使っても同じく遅かったんですよ。UI から実行すると速くてスクリプトから実行すると遅くなる? そんなのアリですか。 しかし、 Get > Material > Constant を実行したときのログを見て気が付いたんですが、 ApplyShader コマンドの引数で指定している Constant ですが、ディスク上の Preset ファイルを "$XSI_DSPRESETS\\Shaders\\Material\\Constant.Preset" という風にフルパス で記述 してますね。 シェーダを与える時にディスク上の Preset ファイルにアクセスするらしいというのは前から知っていたのですが、今回の処理の遅さはこのアクセスに時間がかかっているのかも? と思いました。 そこで、これを真似して記述してみると、0.188秒 (゚∀゚) 10回ループで 0.188秒ですからね。さっきのは同じ10回ループで18秒かかってますから、ちょうど100倍速くなった ことになります。ひゃくばい ですよ。 結果的に速くなったのでまあいいんですが、何故なんだろうと腑に落ちないので、空調屋さんに聞いてみたんですよ。 そしたら、Workgroup が設定してあると遅い という事例があったとのことなんですね。 もちろん、うちの XSI 環境も Workgroup に依存してます。ないとプラグインの管理とかが大変ですからね。 なので試しに Workgroup との接続を切ってみたら、 わっ、速い。劇的に速くなりました。 どうやら、XSI はシェーダの Preset ファイルなどを読みに行くときに、先に Workgroup を探しに行く らしいんですね。 今回のように "Constant" と指定した場合、Constant.Preset ファイルを Workgroup フォルダ以下で探してしまう。 Workgroup はプラグインなど後から追加したものを入れる場所だから、当然ファクトリーシェーダである Constant.Preset ファイルは存在しないわけですよ。そして Workgroup フォルダは複数マシンで共有するという性質上、当然のようにネットワークの先のサーバに置いてあるわけで、なおさらアクセスが遅いのでしょう。 ひと通り Workgroup フォルダを探して見つからなかったら、ローカルにあるインストールフォルダ以下を探して、やっと Constant.Preset にたどり着いたけど何秒もかかっちゃったよ、ということなのでしょう。フルパスで指定すれば、ファイルの場所を明示しているということなので、すぐに Preset ファイルにたどり着けて遅延が発生しないということなのでしょう。たぶん。 ということは多分、Workgroup を設定していたとしても、その Workgroup フォルダがローカルディスク上にある場合は、ここまで処理が遅くなることはないんじゃないのかな。 ま、Workgroup がローカルにあったんじゃそもそも Workgroup の意味があまりないとは思うけど。 ということで、どうやら原因は Workgroup らしいということはわかったんだけど、Workgroup 無しに生きていけるはずもありません。なので、今後は基本的にフルパス表記で行くことにします。 幸いにも $XSI_DSPRESETS などという表記が可能なので(環境変数?って言うのかな?)、XSI のバージョンなどインストール環境に左右されない書き方が可能です。 あと、AddMaterial メソッドでもうひとつ気づいたんですが・・・・。
<p><p><p><p><p><p><p><p>AddMaterial (SceneItem)</p></p></p></p></p></p></p></p>
マニュアルを見ると、
SceneItem.AddMaterila( [Preset] , [BranchFlag], [Name] ) とあります。第3引数は Represents the name of the new Material object つまり、
「マテリアルオブジェクトの名前」 とあります。RenderTree のノードで言うこところの、一番右側、シェーダではなく
マテリアルそのもの のことですね。
しかし RenderTree を見てみると、
マテリアルだけでなく、コンスタントシェーダ(左)の名前まで変更されています。 これはおかしいんじゃない?
と、空調屋さんに聞いてみたら、どうやらバグ、という話でした。
なんでもこの AddMaterial メソッドには、本来はマテリアルの名前を変えるはずなのに、シェーダの名前の方を変えてしまうというバグが昔あったんですって。 そのバグは前に直されたんだけど、どうやらマテリアルの名前にちゃんと反映させる部分だけを修正して、シェーダの名前を変えてしまうという部分は修正されずに放置されたように見える、との話でした。嘔吐デスクに確認を取ったわけではないので、空調屋さんの見解ですけどね。
ま、ほら、なんとも Softimage らしいバグの残し方じゃないですか。
これでいいんですこのソフトウェアは。
なので名前は AddMaterial メソッドで指定しない方がいいですね。上の例なら、
var oMat = Selection(0).AddMaterial("$XSI_DSPRESETS\\Shaders\\Material\\Constant.Preset",false); oMat.name = "FuckMyMaterial"; こうやって2行で書いちゃえばちゃんとマテリアルオブジェクトの方だけ名前を変更できますね。ちょっとめんどくさいけど、これで行きましょう。
ゴルァ
.
最近のコメント