チュートリアル / 読んで触ってよくわかる!Mayaを使いこなす為のAtoZ
第34回:テクスチャの情報を調べてみよう(1/3)
- Maya
- ゲーム
- コラム
- チュートリアル
- マテリアル・シェーダー・UV
- 中級者
- 学生・初心者
- 教育
- 映画・TV
寒くなって来ましたが皆さんいかがお過ごしでしょうか?空気がキリッとするこの時期は寒いながらも気持ちがいいですね。
前回はMayaでのスクリプトの面白さを感じてもらうためにプログラムの解説+ストーリー仕立てでツール制作の流れを紹介しました。
今回もツール制作の流れを初めから終わりまでA to Z で話してみたいと思います。皆さんはMayaで何かツールを作ろうとした時にどうやってMELの機能を探しますでしょうか?こういった部分の知識が日々の作業に効いて来ますし、あまり書籍になって紹介されないので重点的に紹介したいと思います。
さて、今回作るのは「テクスチャ情報を知る」ツールです。
ゲームでも映画でもMayaでテクスチャを管理するのにちょっと情報が足りないと感じることはありませんか?使用しているテクスチャの縦横サイズ、アルファの有無、そういったものがわかると管理しやすくなります。
なんだか難しそうですが順を追ってやっていけばどなたでも実装できますので、早速やって行きましょう!
成果物がわかったほうがヤル気も出ますので、チラリと成果物をお見せします。
こんな感じでテクスチャ情報を見られる様にするのが目標です。
テクスチャ画像なので「texture」という名前がついたMELが無いか検索することにします。
textureという名前のついたMELコマンドが幾つか見つかりますが、UVテクスチャエディタのコマンド(textureWindow)とかがあるだけで、テクスチャサイズを調べるものはないようです。UVテクスチャエディタはtextureWindowでコントロール出来るらしいという情報は、それはそれで後で何かに使えそうですね:)
他の言葉でも調べてみます。
「image」「file」とどちらもポロポロとMELが表示されますが、テクスチャサイズを調べるものは無いようです。
もしかしたら、そもそもMayaではテクスチャサイズがわからないのかしら?
アプローチ方法を変えてMELコマンドではなくfileノードのアトリビュートを見てみることにしましょう。
実はアトリビュートエディタに表示されないアトリビュートがたくさんあります。全てを表示すると見た目がすごいことになりますので、通常必要のないものは表示されないのです。
全てのアトリビュートを確認する方法はいくつかありますが、まずは正当派な方法で行きましょう。アトリビュートエディタのメニューで「Help -> Help On "file"」を選択してfileノードのヘルプを表示します。
ノードのヘルプでは各ノードのアトリビュートと用途が書かれています。英語ですがなんとなく感じ取って下さい…。
まずはそのものズバリ「size」という文字を検索してみます。と、早速ありました!「outSize」というアトリビュート。どうやらこれでテクスチャのサイズが分かるようです。
直接このアトリビュート値を得るには「getAttr」コマンドを使用します。※1
file1というノードのテクスチャサイズを取るとしてこんなスクリプトを実行します。
「2048 2048」と返ってきました!なんのことはなく簡単にサイズが分かりました。
なかなか取るのが難しそうに思えますが、fileノードのヘルプを見てみると「fileHasAlpha」というそのものズバリのアトリビュートがあるではないですか。
なんとラッキーな…。早速実行して値を確かめてみましょう。
アルファがあれば1を返し、なければ0を返すようです。十分事が足ります。
先ほどのgetAttrで取れそうですが、はてアトリビュート名は?
「getAttr file1.imageName;」としてもダメなようです。※2
アトリビュート名を調べたい時に手っ取り早い方法は「適当に値を変えてみる」やり方です。
調べたいアトリビュートの値を適当に変えます。するとスクリプトエディタに履歴としてアトリビュート名と入れた値が表示されますので、それを利用すれば良いのです。値を変えたあとはUndoして元に戻しておくのをお忘れなく!
では適当にテクスチャパスを変えます。すると次のように表示がされます。
「setAttr -type "string" file1.fileTextureName "sourceimages/AlbedoSpec_";」
と出て来ました。次のようにして実行すればテクスチャパスが取れるはずです。
無事テクスチャパスが取れました!
では getAttr へ置き換えるときのコツを幾つか見てみましょう。
履歴では「setAttr」となっています。これを「getAttr」にすればよい、というところまではわかりやすいです。
次に出てくる「-type "string"」は getAttr で無くしています。
getAttr では型の指定がなくても値をとれるので「-type」の指定は無くて大丈夫です。
またgetAttr で「-type」を使うと「対象のアトリビュートの型を返す」ということになってしまい、「string」という文字列が結果として返ってきてしまいます。テクスチャパスが取れなくなってしまいます。というわけで「-type "string"」は無くします。
setAttr の最後にある「"sourceimages/AlbedoSpec_"」も無くします。getAttr は値をセットするのではなく、値を取ってくる機能ですので、特に何も指定する必要がないからです。
意外とこうやって見てみると、いろいろなルールがあるものですね…。
ノードの情報を取るのにMELとgetAttr(これもMELコマンドですが…)のどちらを使うほうが良いのか、迷うと思います。どちらが良いということも無いですが、下記のような特徴があります。
【MELコマンド】
直接欲しい情報を得られる可能性があるので、丁度良いコマンドが見つかればとても便利。
例えば選択しているUVの座標値は「polyEditUV -q -u;」で取れてしまいます。
getAttrでやろうとすると「getAttr meshShape.uvpt[0].uvpx;」とかになり、冗長でメゲそうになる。
【getAttr】
確実にノードのアトリビュート値を知ることができます。polyEditUVとかのMELコマンドが用意されてなくても値をとれます。これを使えば確実ですし、手っ取り早くプログラム出来ることもあります。
ただし場合によってはとても回りくどかったり、泥臭かったり、可読性の悪いコードになります。
※2 Mayaの命名規則
Mayaでは内部で扱うノード名やアトリビュート名に大文字小文字の規則があります。
GUIで表示されている名前は大文字始まりの単語ですが、MELでは通常以下のようなルールがあります。
・空白なし
・一番始めは小文字
・単語ごとに頭が大文字
例えば「Image Name」という文字は、「imageName」のほうがMayaっぽいわけです。
もちろん常にこうであるということはないですし、自分で追加するアトリビュート名もこれに従う必要はないですが、従っておくと無難です。
「E:/Documents/Works/Samples/HSM_Demo/sourceimages/AlbedoSpec_buildingA.tga」
となっています。なんかアトリビュートエディタに出ていたものと違いますね。
まずパスのつなぎに「\」ではなく「/」が使われています。
Mayaは内部的には「\」ではなく「/」を使います。最近「\」にも対応していますがMayaに限らずどんなプログラムでも「\」は特殊な記号でトラブルを起こしがちですので「/」を使うと覚えて下さい。ゲームデータで「\」使うとプログラマさんに怒られます:(
次にアトリビュートエディタではテクスチャパスがプロジェクトフォルダからの相対パスで表示されていますが、内部的には絶対パスを持っていますので、返ってくる値が絶対パスになります。
「/」で文字を区切れば最後の文字がファイル名になるはずです。
tokenizeを使うのも良いのですがMELのヘルプを見てみると「basenameEx」というコマンドがあります。これを使えば手っ取り早くファイル名を抽出できます。次のようなコマンドを実行します。
すると、
「AlbedoSpec_buildingA」
が返ってきました。無事ファイル名が抽出できました!時々こういった便利なコマンドがあったりします。
通常ならこれも「.(ドット)」で文字を区切って取得します。と、ちょっとbasenameExのヘルプを眺めていると「fileExtension() も参照してください。」と書かれていることに気づきます。Extension(拡張子の意)ですからなんとなくそれっぽい機能のにおいがします。
MELのヘルプで「fileExtension」を調べてみるとファイルの拡張子を返してくれるコマンドと書かれています。今回の機能にピッタリですのでこれを使ってみます。次のようなコマンドを実行します。
すると「tga」と返ってきます。バッチリですね!
テクスチャを選択して次のMELを実行すれば、テクスチャのサイズ等の情報がスクリプトエディタに表示されます。
結果はこんな感じです。
テクスチャを選択していなければシーン内全てのテクスチャの情報を表示、という機能も入れればより便利になるかもしれません。大きすぎるテクスチャを表示するとかもいいですね。ぜひ試してみて下さい。
ノードのアトリビュートの調べ方、MELやgetAttrを使った情報の抽出方法もわかってきたのではないでしょうか。
ところでこの機能の使われ方を想像してみると、毎回毎回テクスチャを選択してはMELを実行、というのは辛いですね。テクスチャを選択したらどこかに情報が表示される方が良いです。情報を出すとしたらどこが良いか…。
というわけで基本機能は出来ましたので、次回はGUIに対応して行きましょう。
前回はMayaでのスクリプトの面白さを感じてもらうためにプログラムの解説+ストーリー仕立てでツール制作の流れを紹介しました。
今回もツール制作の流れを初めから終わりまでA to Z で話してみたいと思います。皆さんはMayaで何かツールを作ろうとした時にどうやってMELの機能を探しますでしょうか?こういった部分の知識が日々の作業に効いて来ますし、あまり書籍になって紹介されないので重点的に紹介したいと思います。
さて、今回作るのは「テクスチャ情報を知る」ツールです。
ゲームでも映画でもMayaでテクスチャを管理するのにちょっと情報が足りないと感じることはありませんか?使用しているテクスチャの縦横サイズ、アルファの有無、そういったものがわかると管理しやすくなります。
なんだか難しそうですが順を追ってやっていけばどなたでも実装できますので、早速やって行きましょう!
成果物がわかったほうがヤル気も出ますので、チラリと成果物をお見せします。
こんな感じでテクスチャ情報を見られる様にするのが目標です。
まずはMELドキュメントで調べる
テクスチャの情報を取る…。とりあえず足がかりとしてMELのドキュメントを調べてみましょう。いつでもこんな感じでなんとなくMELのドキュメントを検索して手がかりを掴んでいきます。テクスチャ画像なので「texture」という名前がついたMELが無いか検索することにします。
textureという名前のついたMELコマンドが幾つか見つかりますが、UVテクスチャエディタのコマンド(textureWindow)とかがあるだけで、テクスチャサイズを調べるものはないようです。UVテクスチャエディタはtextureWindowでコントロール出来るらしいという情報は、それはそれで後で何かに使えそうですね:)
他の言葉でも調べてみます。
「image」「file」とどちらもポロポロとMELが表示されますが、テクスチャサイズを調べるものは無いようです。
もしかしたら、そもそもMayaではテクスチャサイズがわからないのかしら?
アプローチ方法を変えてMELコマンドではなくfileノードのアトリビュートを見てみることにしましょう。
ノードからテクスチャ情報を取る
fileノードを選択してアトリビュートエディタを見てみましょう。…特にはサイズに関連する情報は無いようです。実はアトリビュートエディタに表示されないアトリビュートがたくさんあります。全てを表示すると見た目がすごいことになりますので、通常必要のないものは表示されないのです。
全てのアトリビュートを確認する方法はいくつかありますが、まずは正当派な方法で行きましょう。アトリビュートエディタのメニューで「Help -> Help On "file"」を選択してfileノードのヘルプを表示します。
ノードのヘルプでは各ノードのアトリビュートと用途が書かれています。英語ですがなんとなく感じ取って下さい…。
まずはそのものズバリ「size」という文字を検索してみます。と、早速ありました!「outSize」というアトリビュート。どうやらこれでテクスチャのサイズが分かるようです。
直接このアトリビュート値を得るには「getAttr」コマンドを使用します。※1
file1というノードのテクスチャサイズを取るとしてこんなスクリプトを実行します。
getAttr file1.outSize;
「2048 2048」と返ってきました!なんのことはなく簡単にサイズが分かりました。
アルファチャンネルの有無
アルファチャンネルの有無がわかるとかなり便利です。普通にアトリビュートエディタを見ていてもアルファチャンネルがあるのか無いのかわかりませんから。なかなか取るのが難しそうに思えますが、fileノードのヘルプを見てみると「fileHasAlpha」というそのものズバリのアトリビュートがあるではないですか。
なんとラッキーな…。早速実行して値を確かめてみましょう。
getAttr file1.fileHasAlpha;
アルファがあれば1を返し、なければ0を返すようです。十分事が足ります。
ファイル名を調べる
fileノードのアトリビュートエディタを見ると「Image Name」というテキストフィールドがあります。ここに「sourceimages\AlbedoSpec_buildingA.tga」(「\」はMayaだとバックスラッシュ表示だったりします)という名前が入っています。これが取得出来ればなんとかなりそうです。先ほどのgetAttrで取れそうですが、はてアトリビュート名は?
「getAttr file1.imageName;」としてもダメなようです。※2
アトリビュート名を調べたい時に手っ取り早い方法は「適当に値を変えてみる」やり方です。
調べたいアトリビュートの値を適当に変えます。するとスクリプトエディタに履歴としてアトリビュート名と入れた値が表示されますので、それを利用すれば良いのです。値を変えたあとはUndoして元に戻しておくのをお忘れなく!
では適当にテクスチャパスを変えます。すると次のように表示がされます。
「setAttr -type "string" file1.fileTextureName "sourceimages/AlbedoSpec_";」
と出て来ました。次のようにして実行すればテクスチャパスが取れるはずです。
getAttr file1.fileTextureName;
無事テクスチャパスが取れました!
では getAttr へ置き換えるときのコツを幾つか見てみましょう。
履歴では「setAttr」となっています。これを「getAttr」にすればよい、というところまではわかりやすいです。
次に出てくる「-type "string"」は getAttr で無くしています。
getAttr では型の指定がなくても値をとれるので「-type」の指定は無くて大丈夫です。
またgetAttr で「-type」を使うと「対象のアトリビュートの型を返す」ということになってしまい、「string」という文字列が結果として返ってきてしまいます。テクスチャパスが取れなくなってしまいます。というわけで「-type "string"」は無くします。
setAttr の最後にある「"sourceimages/AlbedoSpec_"」も無くします。getAttr は値をセットするのではなく、値を取ってくる機能ですので、特に何も指定する必要がないからです。
意外とこうやって見てみると、いろいろなルールがあるものですね…。
補足
※1 MELコマンド vs getAttrノードの情報を取るのにMELとgetAttr(これもMELコマンドですが…)のどちらを使うほうが良いのか、迷うと思います。どちらが良いということも無いですが、下記のような特徴があります。
【MELコマンド】
直接欲しい情報を得られる可能性があるので、丁度良いコマンドが見つかればとても便利。
例えば選択しているUVの座標値は「polyEditUV -q -u;」で取れてしまいます。
getAttrでやろうとすると「getAttr meshShape.uvpt[0].uvpx;」とかになり、冗長でメゲそうになる。
【getAttr】
確実にノードのアトリビュート値を知ることができます。polyEditUVとかのMELコマンドが用意されてなくても値をとれます。これを使えば確実ですし、手っ取り早くプログラム出来ることもあります。
ただし場合によってはとても回りくどかったり、泥臭かったり、可読性の悪いコードになります。
※2 Mayaの命名規則
Mayaでは内部で扱うノード名やアトリビュート名に大文字小文字の規則があります。
GUIで表示されている名前は大文字始まりの単語ですが、MELでは通常以下のようなルールがあります。
・空白なし
・一番始めは小文字
・単語ごとに頭が大文字
例えば「Image Name」という文字は、「imageName」のほうがMayaっぽいわけです。
もちろん常にこうであるということはないですし、自分で追加するアトリビュート名もこれに従う必要はないですが、従っておくと無難です。
返ってきたパスについて
getAttr で返ってきたファイルへのパスが、「E:/Documents/Works/Samples/HSM_Demo/sourceimages/AlbedoSpec_buildingA.tga」
となっています。なんかアトリビュートエディタに出ていたものと違いますね。
まずパスのつなぎに「\」ではなく「/」が使われています。
Mayaは内部的には「\」ではなく「/」を使います。最近「\」にも対応していますがMayaに限らずどんなプログラムでも「\」は特殊な記号でトラブルを起こしがちですので「/」を使うと覚えて下さい。ゲームデータで「\」使うとプログラマさんに怒られます:(
次にアトリビュートエディタではテクスチャパスがプロジェクトフォルダからの相対パスで表示されていますが、内部的には絶対パスを持っていますので、返ってくる値が絶対パスになります。
ファイル名を抽出する
ファイル名を抽出するにはどうすればよいでしょうか?「/」で文字を区切れば最後の文字がファイル名になるはずです。
tokenizeを使うのも良いのですがMELのヘルプを見てみると「basenameEx」というコマンドがあります。これを使えば手っ取り早くファイル名を抽出できます。次のようなコマンドを実行します。
basenameEx "E:/Documents/Works/Samples/HSM_Demo/sourceimages/AlbedoSpec_buildingA.tga";
すると、
「AlbedoSpec_buildingA」
が返ってきました。無事ファイル名が抽出できました!時々こういった便利なコマンドがあったりします。
ファイルのフォーマットを調べる
ユーザーが拡張子を書き換えているかもしれませんけど、とりあえずファイル名の拡張子を取ることにします。通常ならこれも「.(ドット)」で文字を区切って取得します。と、ちょっとbasenameExのヘルプを眺めていると「fileExtension() も参照してください。」と書かれていることに気づきます。Extension(拡張子の意)ですからなんとなくそれっぽい機能のにおいがします。
MELのヘルプで「fileExtension」を調べてみるとファイルの拡張子を返してくれるコマンドと書かれています。今回の機能にピッタリですのでこれを使ってみます。次のようなコマンドを実行します。
fileExtension "E:/Documents/Works/Samples/HSM_Demo/sourceimages/AlbedoSpec_buildingA.tga";
すると「tga」と返ってきます。バッチリですね!
まとめてみましょう
ではひとつのMELにしてみましょう。テクスチャを選択して次のMELを実行すれば、テクスチャのサイズ等の情報がスクリプトエディタに表示されます。
// 選択している(-sl)、テクスチャノード(-type file)を得ます。
string $nodes[] = `ls -sl -type file`;
// lsで返ってくる値は配列ですが、
// 今回ははじめの一つだけ使うので、別の変数に入れておいて、
// 書きやすくします。[]を毎回書くのは大変だし読みにくい!
string $node = $nodes[0];
// 返ってくる値はxとyのサイズで、floatの配列になっています。
float $size[] = `getAttr ( $node + ".outSize" )`;
// アルファチャンネルの有無。
int $hasAlpha = `getAttr ( $node + ".fileHasAlpha" )`;
// ファイル名と拡張子。
string $path = `getAttr ( $node + ".fileTextureName" )`;
string $fileName = `basenameEx $path`;
string $type = `fileExtension $path`;
// 出力
string $output;
$output = $fileName + ": ";
$output += $size[0] + " x " + $size[1] + ", ";
if ( $hasAlpha ){
$output += "Alpha Exists, ";
} else {
$output += "No Alpha, ";
}
$output += $type + "¥n";
print $output;
string $nodes[] = `ls -sl -type file`;
// lsで返ってくる値は配列ですが、
// 今回ははじめの一つだけ使うので、別の変数に入れておいて、
// 書きやすくします。[]を毎回書くのは大変だし読みにくい!
string $node = $nodes[0];
// 返ってくる値はxとyのサイズで、floatの配列になっています。
float $size[] = `getAttr ( $node + ".outSize" )`;
// アルファチャンネルの有無。
int $hasAlpha = `getAttr ( $node + ".fileHasAlpha" )`;
// ファイル名と拡張子。
string $path = `getAttr ( $node + ".fileTextureName" )`;
string $fileName = `basenameEx $path`;
string $type = `fileExtension $path`;
// 出力
string $output;
$output = $fileName + ": ";
$output += $size[0] + " x " + $size[1] + ", ";
if ( $hasAlpha ){
$output += "Alpha Exists, ";
} else {
$output += "No Alpha, ";
}
$output += $type + "¥n";
print $output;
結果はこんな感じです。
テクスチャを選択していなければシーン内全てのテクスチャの情報を表示、という機能も入れればより便利になるかもしれません。大きすぎるテクスチャを表示するとかもいいですね。ぜひ試してみて下さい。
まとめ
これでとりあえずテクスチャの情報がわかるようになりました。ノードのアトリビュートの調べ方、MELやgetAttrを使った情報の抽出方法もわかってきたのではないでしょうか。
ところでこの機能の使われ方を想像してみると、毎回毎回テクスチャを選択してはMELを実行、というのは辛いですね。テクスチャを選択したらどこかに情報が表示される方が良いです。情報を出すとしたらどこが良いか…。
というわけで基本機能は出来ましたので、次回はGUIに対応して行きましょう。