OSL は、最新の物理に基づいてレンダリングできるように設計されたシェーディング言語で、Arnold 5.0 からサポートされています。OSL を使用すると、Arnold およびその他のレンダラで動作するシェーダを記述できます。 これは C++ シェーダに代わるもので、高度な API を使用して、優れた最適化を実現しながらシェーダの記述を簡単にします。
OSL シェーダは .osl ファイルに記述されており、各ファイルが Arnold の 1 つのシェーダ ノードに対応しています。 次に簡単な例を示します。
shader gamma( color Cin = color(0, 0, 0), float exponent = 1, output color Cout = color(0, 0, 0)) { Cout = pow(Cin, 1/exponent); } |
シェーダ名 gamma
はファイル名 gamma.osl
と一致する必要があります。 このシェーダは、Arnold C++ シェーダとほとんど同じように入力と出力のパラメータを定義しますが、より簡単な構文を使用します。 ここで Cin
および gamma
は入力パラメータで、Cout
は出力パラメータです。 すべてのパラメータは既定値で初期化する必要があります。
シェーダ検索パスのシェーダが Arnold によって発見された場合、シェーダは同一ディレクトリにある .osl ファイルから .oso ファイルに自動的にコンパイルされます。 対応する .oso ファイルが存在しない場合、または .osl ファイルが最後のコンパイルから変更されている場合、これが行われます。
または、Arnold に含まれる oslc
プログラムを使用して、シェーダを手動でコンパイルすることもできます。
$ oslc gamma.osl Compiled gamma.osl -> gamma.oso |
.oso ファイルには、オペレーティング システムと CPU に依存する中間コードが含まれます。 レンダリング時、OSL はシェーダ ネットワークをマシン コードに変換し、シェーダが .osl ソース コードからコンパイルされている場合は分からなかったシェーダ パラメータと他の実行時の値を最大限活用して、処理中にシェーダとネットワークを高度に最適化します。
.osl と .oso ファイルは、.so および .dll シェーダ ファイルと同じ方法でインストールされます。シェーダ検索パスのどこに配置しても、Arnold が発見します。
kick
を使用すると、Arnold がシェーダとそのパラメータを検出したかを確認できます。
$ kick -info gamma node: gamma type: shader output: RGB parameters: 3 filename: gamma.oso version: 4.2.12.0 Type Name Default ------------ -------------------------------- -------------------------------- RGB Cin 0, 0, 0 FLOAT exponent 1 STRING name |
検索パスに自動的に登録された OSL シェーダとは別に、osl
ノードからシェーダを手動でロードすることができます。 これは、シェーダ ネットワークに式を挿入する場合、またはロードするシェーダの内容とそのパラメータの解釈方法を詳細に制御する場合に役立ちます。
osl
にシェーダを指定するには、shadername
パラメータを使用します。.osl または .oso ファイル拡張子は必要ありません。shadername
パラメータが設定されるとすぐに、OSL シェーダ パラメータが先頭に param_
を付けてノードに追加されます。
osl { name myshader shadername somefolder/test param_value 0.5 } |
ネットワークに式を挿入する場合、.OSL または .OSO コードも埋め込むことができます。
osl { name myshader code "shader test(float value = 0, output float result = 0) { result = value * 10; }" param_value 0.5 } |
可能な場合、OSL シェーダ パラメータは対応する Arnold パラメータに変換されます。 Arnold が 1 つのノードでサポートする出力パラメータは 1 つのみです。そのため、複数の出力パラメータがある場合は、最初のパラメータが使用されます。
OSL タイプ | Arnold タイプ |
---|---|
int | INT |
int (メタデータ含む) | BOOLEAN |
int (メタデータ含む) | ENUM |
float | FLOAT |
color | RGB |
color | RGBA |
point | VECTOR |
| VECTOR |
normal | VECTOR |
point |
|
matrix | MATRIX |
あらゆるタイプの配列 | ARRAY |
closure color | CLOSURE |
struct | POINTER |
boolean と enum のパラメータ タイプは整数の OSL メタデータで作成されます。
#define OPTION_A 0 #define OPTION_B 1 #define OPTION_C 2 shader example( int booleanvalue = 0 [[ string widget = "boolean" ]], int enumvalue = 0 [[ string widget = "popup", string options = "OptionA|OptionB|OptionC" ]]) { if (booleanvalue) ... if (enumvalue == OPTION_B) ... } |
ノード パラメータとユーザ データは getattribute()
で入手できます。
// object parameter int id; getattribute("id", id); // object user data color Cs; getattribute("Cs", Cs); // parameter of another node int AA_samples; getattribute("options", "AA_samples", AA_samples); |
getattribute()関数でオブジェクト名パラメータを指定している場合、次のアトリビュートを使用すると、そのオブジェクトに固有の値を取得できます。 名前が付いている特定のオブジェクトがない場合は、現在のオブジェクトが自動的に適用されます。
名前 | タイプ | 説明 |
---|---|---|
"geom:type" | string | オブジェクト タイプ |
"geom:name" | string | オブジェクト名 |
"geom:bounds | point[2] | ワールド空間のオブジェクト バウンディング ボックス(min、max) |
"geom:objbounds" | point[2] | オブジェクト空間のオブジェクト バウンディング ボックス(min、max) |
getattribute()関数でオブジェクト名パラメータを指定し、それが有効なカメラ名である場合、次のアトリビュートを使用すると、そのカメラに固有の値を取得できます。 名前が付いている特定のカメラがない場合は、グローバルまたは既定のカメラが自動的に適用されます。
名前 | タイプ | 説明 |
---|---|---|
"camera:screen_window" | int[2] | イメージの解像度 |
"camera:pixelaspect" | float | ピクセルのアスペクト比(Pixel Aspect Ratio) |
"camera:projection" | string | カメラ タイプ |
"camera:fov" | float | ビューのフィールド |
"camera:clip_near" | float | 近接クリップの距離 |
"camera:clip_far" | float | 遠方クリップの距離 |
"camera:clip" | float[2] | 近接および遠方クリップの距離 |
"camera:shutter_open" | float | シャッターが開く時間 |
"camera:shutter_close" | float | シャッターが閉じる時間 |
"camera:shutter" | float[2] | シャッターが開く時間と閉じる時間 |
"camera:screen_window" | float[4] | 画面ウィンドウ(xmin、min、xmax、ymax) |
Arnold は、P
、u
、v
、N
、Ng
、time
など、ほとんどの OSL シェーダ グローバルをサポートします。 つまり、C++ シェーディング API と同じということです。
Ps
(ライト フィルタ用)、surfacearea()
、dtime
、および dPdtime
の各シェーダ グローバルは、現在サポートされていません。
すべてのシェーダ グローバルは読み取り専用とみなされており、出力クロージャまたはディスプレイスメントへの
および Ci
P
の書き込みはサポートしていません。 その代わりに、出力パラメータを使用する必要があります。
テクスチャには、texture()
と gettextureinfo(
) のビルトイン関数を使用してアクセスします。 texture()
関数はオプションで colorspace
引数を指定し、変換するテクスチャのカラー スペースを示します。
Arnold C++ シェーディング API とは異なり、テクスチャの原点は左下隅ではなく左上隅にあるとみなされることに注意してください。これは、OSL 標準との整合性をとるためです。これに一致するよう、v
座標を 1 - v
に、また UDIM テクスチャの場合は floor(v) + 1 - mod(v, 1)
に反転することができます。
// look up texture color color tex = texture(filename, u, v); // query texture resolution int resolution; gettextureinfo(filename, "resolution", resolution); |
ボリューム チャネルは、オブジェクト スペース座標を使用して texture3d()
から入手できます。
point Po = transform("object", P); float density = texture3d("density", Po, "interp", "bicubic"); |
次のクロージャがサポートされており、C++ シェーダ API のクロージャと一致します。
closure color emission(); closure color background(); closure color diffuse(normal N); closure color oren_nayar (normal N, float sigma); closure color oren_nayar(normal N); closure color translucent(normal N, float sigma); closure color translucent(normal N); closure color sheen(normal N, float roughness); closure color metal(string distribution, normal N, vector U, color n, color k, float xalpha, float yalpha); closure color microfacet(string distribution, normal N, vector U, float xalpha, float yalpha, float eta, int refract); closure color microfacet(string distribution, normal N, float alpha, float eta, int refr); closure color reflection(normal N, float eta); closure color reflection(normal N); closure color refraction(normal N, float eta); closure color transparent(); closure color holdout(); closure color empirical_bssrdf(vector mfp, color albedo); closure color randomwalk_bssrdf(vector mfp, color albedo, float g); closure color volume_absorption(); closure color volume_emission(); closure color volume_henyey_greenstein(color absorption, color scattering, color emission, float g); closure color volume_matte(); |
クロージャを出力するサンプル シェーダ:
shader simple_diffuse( color albedo = 0.8, float opacity = 1.0, output closure color result = 0) { result = opacity * albedo * diffuse(N) + (1 - opacity) * transparent(); } |
OSL trace()
関数は、プローブ線のトレースでサポートされています。 シェーディングを実行する shade
引数はサポートされていません。 traceset
引数はサポートされています。既定では inclusive traceset を使用し、traceset 名の接頭辞が -
の場合は exclusive traceset を使用します。
ヒットについての情報は、hit
、hitdist
、P
、N
、u
、v
をサポートする getmessage()
、およびヒットしたオブジェクト上の任意のユーザ データとパラメータ ルックアップとともに取得されます。
int hit = trace(origin, direction, "traceset", tracesetname); if (hit) { // query hit distance float hitdist; getmessage("trace", "hitdist", hitdist); // query parameter on object that was hit string name; getmessage("trace", "name", name); // query user data on position where object was hit color Cs; if (getmessage("trace", "Cs", Cs)) ...; } |
OSL raytype(<ray type>)関数は、シェーディングされているレイが指定されたタイプのものである場合は 1、指定されたタイプでない場合またはレイのタイプ名がレンダラによって認識されない場合は 0 を返します。
サポートされているレイのタイプ |
---|
'camera" |
"shadow" |
'diffuse_transmit" |
'specular_transmit" |
'volume_scatter" |
'diffuse_reflect" |
'specular_reflect" |
'subsurface" |
OSL シェーダおよび C++ シェーダは単一のシェーダ ネットワークにリンクすることができます。ただし、OSL シェーダの出力を C++ シェーダに関連付けるために、オーバーヘッドが少し(レンダリング時間全体の 1 ~ 2 %)発生します。OSL オプティマイザーがネットワーク全体を積極的に最適化できるようにするには、できるだけ多くの OSL シェーダ ノードを使用する必要があります。
レンダリング中にシェーダが初めて評価されるときに、OSL シェーダのランタイム コンパイルと最適化が行われます。 このため、最初のピクセルまでの時間は長くなりますが、レンダリング全体の時間は短縮されます。
OSL_OPTIONS 環境変数を使用すると、シェーダで共通するエラーをデバッグしたり、詳細情報を出力したりできます。
# Add (expensive) code to find array out of bounds access, NaN/Infs and use of uninitialized variables OSL_OPTIONS="range_checking=1,debug_nan=1,debug_uninit=1" # Issue info messages for every shader compiled OSL_OPTIONS="compile_report=1" # Number of warning calls that should be processed per thread OSL_OPTIONS="max_warnings_per_thread=100" |