【OSL入門】MayaでArnoldのシェーダーを書く①

OSLコードとシェーダーノード、グレースケールの3D球体を並べた「OSL入門①」のアイキャッチ Tech

はじめに

OSL とは、Open Shading Language という ソニー・ピクチャーズ・イメージワークスによって開発されたシェーディング言語のことです。

Maya では特別なプラグインやエディタ無しで OSL を使用できる便利なノードが用意されています。
それを使えば、シェーディングに必要な計算処理を Maya の中で書いてそのまま使用できます。

MayaではArnoldレンダリング用に ai○○ と名付けられた便利なノードが数多く用意されていますが、これを自作できるようなイメージです!

ArnoldのHelpで作例を見ることができます。

Help

この記事では、初心者向けに OSL の書き方と実際に Arnold で使用する方法を解説します。

変数代入といった多くのプログラミング言語に共通する基礎的な用語については、ほとんど説明せずに使用することがあるので、何か一つ以上、プログラミング言語( MELでもOK )を入門したことがあると理解しやすいと思います。

必要な前提知識

  • Maya の基礎知識( Arnold によるレンダリング含む )
  • ノードエディタ等を使用したノードの接続
  • プログラミング言語の基礎(必須ではないがあるといい)

Arnold で OSL シェーダーをレンダリングする基本的な手順

aiOslShaderの作成

ノードエディタで tab キーを押し、aio と入力し aiOslShader を作成します。

MayaのNode Editorで「aio」と検索し、候補からaiOslShaderノードを選択している画面

コードのコンパイル

作成した aiOslShader を選択し、Attribute Editor を確認すると、OSL code というタブにOSLを記入できる欄があります。

aiOslShaderのAttribute Editorに表示されたOSL Code入力欄

まずはここに以下のコードをコピペで貼り付けてください。コードの内容については後ほど説明します。

shader sample_shader(
    color inputColor = color(1.0, 0.0, 0.0),
    output color outColor = 0
){
    outColor = inputColor;
}

コードをコピペしたり編集するだけでは、結果に反映されません。Compile OSL Codeをクリックすることで編集が適用されます。
成功した場合、 Compile Status が Compile Successとなります。

aiOslShaderでOSLコードをコンパイルし、Compile StatusにCompile Successと表示された画面

タイプミスやエラーを含む場合、 Compile Status は Compile Failureとなります。
この場合は、コードを正しく修正して再度 Compile OSL Code すればOKです。

Compile StatusにCompile Failureが表示され、カンマ不足によるコンパイルエラーを確認している画面
,が抜け落ちエラーになった例

うまくいっていれば、ノードに input Color と out Color というアトリビュートが増えているはずです。
ノードエディタでこのアトリビュートを表示するには、ノードを選択して3番キーを押してください。

Node EditorのaiOslShaderにInput ColorとOut Colorのアトリビュートが追加された状態

オブジェクトへの割り当て

次に、Arnold の適当なマテリアルを作成してオブジェクトに割り当てます。
ここではシンプルな色をそのまま出力できる aiFlat ノードを割り当てました。

MayaでaiFlatマテリアルを作成し、レンダリング対象のオブジェクトへ割り当てた状態

aiOslShader の Out Color を aiFlat の outColor の代わりに Shading Group ( aiFlat1SG ) の Surface Shader に接続します。

Node EditorでaiOslShaderのOut ColorをShading GroupのSurface Shaderへ接続したノード構成

Arnold RenderView を開きレンダリングして、オブジェクトが赤く表示されれば正常です。

  • 更新が反映されない場合は、Compile OSL Code のたびに Arnold RenderView の Render > Update Full Scene (ctrl+U)でシーンを更新してレンダリングしてください。
  • 今回の例のように出力が単なる色であれば、SG の Surface Shaderにつなぐ代わりに、aiFlatのColorにつなぐだけでもOKです。ただし、出力の種類によってはこの方法は使用できません。

入力値の変更

aiOslShader を選択して attribute Editor を確認すると、コード入力欄の下に作成した入力アトリビュートが表示されます。

aiOslShaderのAttribute Editorに作成したInput Colorアトリビュートが表示された画面

Attribute Editor で input Color をデフォルトの赤からほかの色に変えることで、レンダリング結果に反映されます。(反映されない場合は Arnold RenderView でupdate Full Scene を試してください。)

以上が、aiOslShader の基本的な使い方です。

OSLの書き方

OSL の全体像は次のようなかなりシンプルな構造になっています。

shader シェーダー名( 入出力 ) { 処理内容; }

シェーダー名は好きな名前で問題ないので、ここでは sample_shader とします。(全角文字、空白、アンダーバー以外の記号、先頭の数字等は使用できません。)
また、OSL は単語の途中でなければ改行をしても結果に影響しないので、見やすいように改行します。

shader sample_shader(
    // 入出力
){
    // 処理内容;
}

入出力の部分に項目を追加すると、aiOslShader ノードのアトリビュートを増やすことができます。
例えば、input1 という名前の小数アトリビュートを追加したい場合は以下のようにします。

shader sample_shader(
    float input1 = 3.0
){

}

3.0は初期値です。

float というのは実数を浮動小数点形式で扱った型のことです。
そのアトリビュートが整数なのか、実数なのか、色なのか、これを型と呼びますが、入出力では型を明記する必要があります。

型名意味初期値の例
float実数(浮動小数点数)4.2 / 0.0 / -3.0
int整数4 / 0 / -3
colorcolor(1.0, 0.0, 0.0)
point座標point(2.0, 3.0, 4.0)
vectorベクトル(方向)vector(5.0, 6.0, 7.0)
normal法線normal(0.0, 0.0, 1.0)
string文字列“” / “Hello World” / “osl”

出力アトリビュートを作成したい場合は、型の前に output をつけます。
何もつけない場合は、入力として扱われます。
また、入出力が複数になる場合は、,(カンマ)で区切ります。忘れるとコンパイルエラーになるので注意しましょう。

shader sample_shader(
    float input1 = 3.0,
    output float output1 = 2.0
){

}

この状態でコンパイル(Compile OSL Code)すると、input1という入力アトリビュートと、output1 という出力アトリビュートがノードに追加されます。

OSLコードのコンパイル後、aiOslShaderにinput1とoutput1のアトリビュートが追加された状態

Node Editor メニューの Attribute Names で設定される表示が Nice Name になっている場合、OSL 上で設定したアトリビュート名(シェーダーパラメータ名)通りとは限りません。

_(アンダーバー)や大文字があると、自動で区切って表示されます。

例えば outColor は out Color に、inputColor は input Color になります。

色やベクトルを入力する場合の初期値は、以下のように color(R, G, B) や vector(X, Y, Z)のように書きます。

shader sample_shader(
    color inputColor = color(1.0, 0.0, 0.0),  // RGB値(1.0, 0, 0) つまり赤
    vector inputVector = vector(1.0, 0.0, 0.0) // X軸方向の単位ベクトル
){
}

// に続くテキストは改行されるまで単なるコメントとして扱われ、処理結果に影響しません。
/* と */で囲まれたテキストも同様にコメントとして扱われます。こちらはコメント内に改行を入れることができます。

入出力はいくつも追加可能です。

これによってほかのノードの情報をアトリビュートの接続によって取得し、好きに計算処理をして出力することができます。

入出力が書けたら、実際の処理は {} の中に書きます。

計算結果は出力しなければ意味がないので、最終的にはoutputを上書きします。

シンプルな例として、以下では入力された色をそのまま出力する OSL を示します。
このコードは最初にコピペで実行したサンプルコードと全く同じです。

shader sample_shader(
    color inputColor = color(1.0, 0.0, 0.0),
    output color outColor = 0
){
    outColor = inputColor;
}

=はプログラミング言語において一般的に代入を表し、右側の結果を左側に記録します。
Maya のノードの接続に置き換えると、右のアトリビュートを左のアトリビュートにつなぐ操作に相当します。

outputとして用意したoutColor、inputColorによって上書きすることで、入力された色がそのまま出力されます。

Input Colorの赤をOut Colorへそのまま渡したOSLシェーダーのレンダリング結果

しかし、このままだと受け取った色をそのまま次のノードに受け渡しているだけで、何の役割も果たせません。
そこで、入力した色をグレースケールに置き換えてみたいと思います。

OSL では、inputColor[i] のように[]の中に0始まりの番号(インデックス)を入れることで、i番目の要素を取り出すことができます。

color 型の変数は、RGB 値が R,G,B の順番に記録されているので、inputColor[0]とすると、Rの値が取り出せます。

取り出したRの値は0.0から1.0の範囲の小数なので、新たにfloat型の変数に代入することができます。※ color型自体に0.0から1.0の範囲制限はありません。

float R = inputColor[0];
float G = inputColor[1];
float B = inputColor[2];

RGB 値をもとに次の式で輝度 Y を求めることができます。(Rec.709の線形RGBを前提とした係数を用いています。色空間によって、適切な係数が異なる点に注意してください。)

Y=0.2126×R+0.7152×G+0.0722×BY = 0.2126 × R + 0.7152 × G + 0.0722 × B

OSL では、多くのプログラミング言語と同じような要領で、四則演算が行えます。
掛け算の記号は×の代わりに*(半角のアスタリスク)を使用します。

float Y = 0.2126 * R + 0.7152 * G + 0.0722 * B;

R,G,B が いずれも 0.0~1.0 の値であれば、Y は0.0~1.0の値をとる小数になります。
R、G、B すべてにこの値を設定すると、グレースケールを出力することができます。
OSL では R, G, B 値がすべて同じ値の場合、color(Y, Y, Y) を省略して color(Y) と書くことができます。

以上をすべて反映すると以下のようになります。

shader sample_shader(
    color inputColor = color(1.0, 0.0, 0.0),
    output color outColor = 0
){
    float R = inputColor[0];
    float G = inputColor[1];
    float B = inputColor[2];
    float Y = 0.2126 * R + 0.7152 * G + 0.0722 * B;
    outColor = color(Y);
}

これで、入力した色をグレースケールに変換するシェーダーの完成です。

入力色をRec.709の係数でグレースケールへ変換したOSLシェーダーのレンダリング結果

まとめ

この記事では、Mayaで実際にOSLシェーダーを書いてArnoldでレンダリングする手順と、シンプルなOSLシェーダーの書き方を解説しました。

次回に続きます。

次回の記事 → 【OSL入門】MayaでArnoldのシェーダーを書く②~標準関数とグローバル変数~

コメント

タイトルとURLをコピーしました