Chapter07

1. イントロダクション
2. 概要
3. 字句構造
4. 全体的な構文...
5. データ型
6. 言語構文
7. **標準ライブラリ関数**
8. 形式言語文法
9. シェーダグループの記述
10. 用語集
11. Light Path Ex...

### 7.1.2 数学関数

これらの関数のほとんどは、**float**、**color**、**point**、**vector**、**normal**などの汎用型に対して動作します。
**color**と**point**系の型に関しては、成分ごと(**x**、**y**、**z**に対して別々に)に計算が実行されます。

type **radians** (type deg)

type **degrees** (type rad)

度からラジアン、ラジアンから度に変換します。
type **cos** (type x)

type **sin** (type x)

type **tan** (type x)

**x**(単位はラジアン)のコサイン、サイン、タンジェントを計算します。
void **sincos** (type x, output type sinval, output type cosval)

**x**（単位はラジアン）のサインとコサインの両方を計算します。どちらも必要な時は、この関数の方が**sin()**と**cos()**を別々にコールするよりも負荷が軽いです。
type **acos** (type x)

type **asin** (type y)

type **atan** (type y\_over\_x)

type **atan2** (type y, type x)

**acos()**と**asin()**はそれぞれアークコサイン、アークサインの主値を計算します。その引数の値は、有効な定義域になるようにまず最初に[−1, 1]にクランプされます。
**acos()**に関しては、その結果は必ず[0, π]の範囲内に、**asin()**と**atan()**に関しては、[−π/2, π/2]の範囲内になります。**atan2()**に関しては、両方の引数の符号から戻り値の象限を決定します。
type **cosh** (type x)

type **sinh** (type x)

type **tanh** (type x)

**x**（単位はラジアン）のハイパボリックコサイン、ハイパボリックサイン、ハイパボリックタンジェントを計算します。
type **pow** (type x, type y)

type **pow** (type x, float y)

x

y

{\displaystyle x^{y}}

を計算します。この関数は、**pow(-1,0.5)**などの"定義できない"演算に対しては0を返します。
type **exp** (type x)

type **exp2** (type x)

type **expm1** (type x)

それぞれ

e
x

{\displaystyle e^x}

,

2
x

{\displaystyle 2^x}

,

e

x

−
1

{\displaystyle e^{x}-1}

を計算します。**expm1(x)**は、非常に小さな値の**x**でも精度が良いです。
type **log** (type x)

type **log2** (type x)

type **log10** (type x)

type **log** (type x, float b)

それぞれ基底が

e

{\displaystyle e}

,2,10,任意の基底**b**の**x**の対数を計算します。
type **logb** (type x)

**x**の指数を浮動小数点として返します。
type **sqrt** (type x)

type **inversesqrt** (type x)

x

{\displaystyle \sqrt{x}}

と

1

/

x

{\displaystyle 1/\sqrt{x}}

を計算します。**x <0**なら0を返します。
type **cbrt** (type x)

x
3

{\displaystyle \sqrt[3]{x}}

を計算します。戻り値の符号はxと一致します。
float **hypot** (float x, float y)

float **hypot** (float x, float y, float z)

それぞれ

x
2

y
2

{\displaystyle \sqrt{x^2 + y^2}}

と

x

2

y

2

z

z

{\displaystyle {\sqrt {x^{2}+y^{2}+z^{z}}}}

を計算します。
type **abs** (type x)

type **fabs** (type x)

**x**の絶対値（これら2つの関数は同じ意味です）。
type **sign** (type x)

**x > 0**なら1、**x < 0**なら-1、**x = 0**なら0を返します。
type **floor** (type x)

type **ceil** (type x)

type **round** (type x)

type **trunc** (type x)

色々な概数化メソッド: **floor**は**x**以下の最大の整数を返し、**ceil**は**x**以上の最小の整数を返します。**round**は両側から**x**に最も近い整数を返し、**trunc**は**x**の整数部を返します（これは、**x>0**の場合は**floor**、**x<0**の場合は**ceil**と等価です）。
type **fmod** (type a, type b)

type **mod** (type a, type b)

**fmod()**関数は**a/b**の浮動小数点の余りを返します。つまり、浮動小数点版の整数**%**演算子です。
これは、C/C++の**fmod**関数とほぼ同じです。ただし、OSLの場合は、**fmod(a,0)**はNaNではなく0を返します。**a < 0**なら、その戻り値はマイナスになります。
**mod()**関数は**a−b\*floor(a/b)**を返します。これは必ず0以上の数値を返します。
例えば、**fmod(-0.25, 1.0) = -0.25**ですが、**mod(-0.25, 1.0) = 0.75**です。
プラスの数値**a**に限っては、どちらの関数も同じ値を返します。
どちらの関数でも、その**type**には**float**、**point**、**vector**、**normal**、**color**のどれかを指定することができます。
type **min** (type a, type b)

type **max** (type a, type b)

type **clamp** (type x, type minval, type maxval)

**min()**と**max()**関数は、2つ以上の値のリストからそれぞれ最小値、最大値を返します。
**clamp**関数は、
```
min(max(x, minval), maxval)
```
を返します。つまり、指定した範囲にクランプされた**x**の値を返します。
type **mix** (type x, type y, type alpha)

type **mix** (type x, type y, float alpha)

**mix**関数は、線形ブレンド:

x
∗
(
1
−
α
)
y
∗
(
α
)

{\displaystyle x\*(1-\alpha )+y\*(\alpha )}

を返します。type **select** (type x, type y, type cond)

type **select** (type x, type y, float cond)

type **select** (type x, type y, int cond)

**select**関数は**cond**が0なら**x**、**cond**が0以外なら**y**を返します。
これは、**(cond ? y : x)**とほぼ等価ですが、**cond**が（**color**などの）成分ベースの型であれば、選択は成分ごとに発生します。根本的な実装は本物の条件文ではなく、分岐ペナルティは発生しないと推定される。
int **isnan** (float x)

int **isinf** (float x)

int **isfinite** (float x)

**isnan()**関数は**x**が非数（NaN）であれば1、そうでなければ0を返します。
**isinf()**関数は**x**が無限（Infもしくは–Inf）であれば1、そうでなければ0を返します。
**isfinite()**関数は**x**が普通の数値（無限でも非数でもない）であれば1、そうでなければ0を返します。
float **erf** (float x)

float **erfc** (float x)

**erf()**関数は、誤差関数

e
r
f

(
x
# )

2

π

∫

0

x

e

−

t

2

d
t

{\displaystyle {\mathrm {erf} (x)={\frac {2}{\sqrt {\pi }}}\int \_{0}^{x}e^{-t^{2}}}dt}

を返します。**erfc**は、相補誤差関数**1-erf(x)**（これは、大きな値の**x**に対して精度を維持するのに役立ちます）を返します。
### 7.2 ジオメトリ関数

ptype **ptype** (float f)

ptype **ptype** (float x, float y, float z)

各**float**値からpoint系の値（**ptype**は**point**、**vector**、**normal**のいずれか）を構築します。
単一**float**から構築した場合には、その値が**x**、**y**、**z**にコピーされます。
ptype **ptype** (string space, float f)

ptype **ptype** (string space, float x, float y, float z)

名前の付いた座標系を基準に各**float**座標からポイント系の値（**ptype**には**point**,**vector**,**normal**を指定することができます）を構築します。つまり、
```
point (space, x, y, z)
```
は、
```
transform (space, "common", point(x, y, z))
```
と等価です。
（**vector**、**normal**も同様）
float **dot** (vector A, vector B)

2つのベクトル(または法線)の内積、つまり、

A
⋅
# B

A

x

B

x

A

y

B

y

A

z

C

z

{\displaystyle A\cdot B=A\_{x}B\_{x}+A\_{y}B\_{y}+A\_{z}C\_{z}}

を返します。
vector **cross** (vector A, vector B)

2つのベクトル（または法線）の外積、つまり、

A
×
B

{\displaystyle A \times B}

を返します。
float **length** (vector V)

float **length** (normal V)

ベクトルまたは法線の長さを返します。
float **distance** (point P0, point P1)

2点間の距離を返します。
float **distance** (point P0, point P1, point Q)

**P0**と**P1**を結んだ線分と**Q**との最短距離を返します。
vector **normalize** (vector V)

normal **normalize** (normal V)

**V**と同じ方向の長さ1のベクトル、つまり、**V / length(V)**を返します。
vector **faceforward** (vector N, vector I, vector Nref)

vector **faceforward** (vector N, vector I)

**dot(Nref, I) < 0**なら**N**を、そうでないなら**-N**を返します。2つの引数だけを渡す関数に関しては、**Nref**は暗黙的に**Ng**（本来のサーフェス法線）が指定されます。この関数の特徴は、カメラの方へ向いた（つまり**I**の「反対」向きの）バージョンの**N**を返します。この状況についてさらに詳しく説明するために、Open Shading Languageで表現される**faceforward**の実装を以下に示します：
```
vector faceforward (vector N, vector I, vecor Nref)
{
    return (I.Nref > 0) ? -N : N;
}

vector faceforward (vector N, vector I)
{
    return faceforward (N, I, Ng);
}
```

vector **reflect** (vector I, vector N)

入射ベクトル**I**とサーフェス方向**N**から、**R = I - 2\*(N.I)\*N**の反射方向を返します。
この数式が正しく動作するには、**N**が（単位長に）正規化されていなければなりません。
vector **refract** (vector I, vector N, float eta)

スネルの法則を使って、入射ベクトル**I**とサーフェス方向**N**から屈折方向を返します。**eta**パラメータは、**I**を含んだ媒体の屈折率を、その**I**が入射した媒体の屈折率で割った比率です。その結果は必ずしも正規化されているわけでなく、全内部反射の場合にはゼロ長のベクトルが返されます。参考として、以下がその実装に相当するOpen Shading Languageの記述です:
```
vector refract (vector I, vector N, float eta)
{
    float IdotN = dot (I, N);
    float k = 1 - eta*eta * (1 - IdotN*IdotN);
    return (k < 0) ? vector(0,0,0) : (eta*I - N * (eta*IdotN + sqrt(k)));
}
```

vector **fresnel** (vector I, normal N, float eta,

                             output float Kr, output float Kt,

                             output vector R, output vector T);

**fresnel**は、スネルの法則とフレネル方程式に応じて、反射方向ベクトル**R**と透過方向ベクトル**T**をそれぞれ計算し、さらに、反射光のスケール係数**Kr**、透過光のスケール係数**Kt**も計算します。
**I**パラメータは正規化された入射光線で、**N**は正規化されたサーフェス法線で、**eta**は、Iを含んだ媒体の屈折率を、その**I**が入射した媒体の屈折率で割った比率です。
point **rotate** (point Q, float angle, point P0, point P1)

ptype **rotate** (point Q, float angle, vector axis)

点**Q**を、点**P0**から点**P1**に通過する軸、または原点を中心とする**axis**ベクトルに対して**angle**ラジアンだけ回転させた点を返します。
ptype **transform** (string tospace, ptype p)

ptype **transform** (string fromspace, string tospace, ptype p)

ptype **transform** (matrix Mto, ptype p)

（**ptype p**引数のタイプに応じて）**point**、**vector**、**normal**を**fromspace**座標系から**tospace**座標系に変換します。**fromspace**を指定しなかった場合、その**p**は**common**空間座標であると見なされるので、**common**空間から**tospace**空間に変換が行なわれます。名前で座標系を指定する方法以外にも、4×4 matrixを直接渡すことができます。
渡した点**p**のタイプに応じて、異なる変換セマンティクスが使用されます。**point**は位置として、**vector**は位置に関係なく方向として変換され、**normal**は非線形スケール下でサーフェスへの直交性が維持されるように**vector**とは微妙に異なる変換が行なわれます。
float **transformu** (string tounits, float x)

float **transformu** (string fromunits, string tounits, float x)

単位を**fromunits**から**tounits**に変換します。**fromunits**を指定しなかった場合、その**x**は**common**空間単位であると見なされます。
長さの変換に関しては、単位名には**mm**、**cm**、**m**、**km**、**in**、**ft**、**mi**のいずれか、または、**common**、**world**、**shader**を含む座標系の名前、レンダラーが対応している他の名前の座標系を指定することができます。
時間の変換に関しては、単位名には**s**、**frames**、または**common**（これは、レンダラーが使用する時間単位を意味します）のどれかを指定することができます。
長さ単位を他の長さ単位に、時間単位を他の時間単位に変換する場合にのみ有効です。長さを時間またはその逆の変換をしようとすると、エラーになります。通貨単位を時間に変換しようと考えてはいけません。
### 7.3 カラー関数

color **color** (float f)

color **color** (float r, float g, float b)

個々の**float**値から**color**を構築します。単一**float**から構築した場合、その値が**r**、**g**、**b**にコピーされます。
color **color** (string colorspace, float f)

color **color** (string colorspace, float r, float g, float b)

指定した名前のカラー空間内の個々の**float**値と等価なRGBカラーを構築します。つまり、
```
color (colorspace, r, g, b)
```
は、
```
transformc (colorspace, "rgb", color(r, g, b))
```
と等価です。
float **luminance** (color rgb)

color **rgb**の線形輝度を返します。この輝度は、ITU-R規格の0.2126R + 0.7152G + 0.0722Bで実装されています。
color **blackbody** (float temperatureK)

**blackbody()**関数は、与えられたケルビン温度のマテリアルから予想される黒体放射を単位

W

/

m

2

{\displaystyle W/m^{2}}

で返します。
**emission()**の単位は放射輝度であるため、

W

/

m

2

/

s
r

{\displaystyle W/m^{2}/sr}

に変換するためにサーフェスには1/π、ボリュームには1/4πのスケール係数が必要になります。
color **wavelength\_color** (float wavelength nm)

指定された波長(nm単位)の純粋なスペクトル色の知覚色に可能な限り一致するRGBカラーを返します。
color **transformc** (string fromspace, string tospace, color Cfrom)

color **transformc** (string tospace, color Cfrom)

color **Cfrom**を**fromspace**色空間から**tospace**色空間に変換します。**fromspace**を指定しなかった場合、**rgb**空間からの変換と見なされます。
### 7.4 マトリックス関数

matrix **matrix** (float m00, float m01, float m02, float m03,

                             float m10, float m11, float m12, float m13,

                             float m20, float m21, float m22, float m23,

                             float m30, float m31, float m32, float m33)

16個の**float**値から行優先順で**matrix**を構築します。
matrix **matrix** (float f)

対角線上の成分がすべて**f**で、それ以外の成分がすべて0の**matrix**を構築します。つまり、**matrix(1)**は単位行列で、**matrix(f)**は**f\*matrix(1)**です。
matrix **matrix** (string fromspace, float m00, ..., float m33)

matrix **matrix** (string fromspace, float f)

指定した名前の空間を基準に**matrix**を構築し、そこに**space-to-common**変換行列を乗算します。座標系の名前が不明だった場合は、それは単位行列と見なされます。
**matrix(space, 1)**は**space-to-common**変換行列を返します。その座標系の名前が不明だった場合は、それは単位行列と見なされます。
matrix **matrix** (string fromspace, string tospace)

**fromspace**から**tospace**への座標変換に使用できる**matrix**を構築します。
どちらかの座標系の名前が不明だった場合は、それらは単位行列と見なされます。
int **getmatrix** (string fromspace, string tospace, output matrix M)

**fromspace**から**tospace**への座標変換を行なう**matrix**を**M**に設定します。
成功すれば1、座標系の名前が不明だった場合（この場合、**M**は変更されません）は0を返します。
これは、**matrix(from, to)**コンストラクタと非常に似ていますが、**getmatrix**では、シェーダは不明な座標系の名前を上手く制御することができます。
float **determinant** (matrix M)

matrix **M**の行列式を計算します。
matrix **transpose** (matrix M)

matrix **M**の転置行列を計算します。
### 7.5 パターン生成

float **step** (float edge, float x)

type **step** (type edge, type x)

**x < edge**なら0、**x ≥ edge**なら1を返します。
**type**には、**float**、**color**、**point**、**vector**、**normal**のどれかを指定することができます。
**color**と**point**系の型に関しては、成分ごと（**x**、**y**、**z**は個別）に計算が実行されます。
float **linearstep** (float edge0, float edge1, float x)

float **linearstep** (type edge0, type edge1, type x)

**x ≤ edge0**なら0、**x ≥ edge1**なら1を返し、**edge0 < x < edge1**の時は、0から1の間で線形補間が実行されます。これは、edge0 == edge1のときのstep(edge0, x)と等価です。**color**と**point**系の型に関しては、成分ごと（**x**、**y**、**z**は個別）に計算が実行されます。
float **smoothstep** (float edge0, float edge1, float x)

type **smoothstep** (type edge0, type edge1, type x)

**x ≤ edge0**なら0、**x ≥ edge1**なら1を返し、**edge0 < x < edge1**の時は、0から1の間で滑らかなエルミート補間が実行されます。これは、閾値関数を滑らかに遷移させたい場合に役立ちます。
**type**は**float**、**color**、**point**、**vector**、**normal**のどれかです。**color**と**point**系の型に関しては、成分ごと（**x**、**y**、**z**は個別）に計算が実行されます。
float **smooth\_linearstep** (float edge0, float edge1, float x, float eps)

float **smooth\_linearstep** (type edge0, type edge1, type x, type eps)

この関数は、**edge0 + eps**から**edge1 − eps**の間では厳密に線形になりますが、**edge0 − eps**から**edge0 + eps**の間では滑らかに0に遷移し、**edge1 − eps**から**edge1 + eps**の間では滑らかに1に遷移します。
これは、**x ≤ edge0 − eps**なら0、**x ≥ edge1 + eps**なら1になり、**edge0 < x < edge1**の時は、0から1の間で線形補間が実行されます。**color**と**point**系の型に関しては、成分ごと（**x**、**y**、**z**は個別）に計算が実行されます。
type **noise** (string noisetype, float u, ...)

type **noise** (string noisetype, float u, float v, ...)

type **noise** (string noisetype, point p, ...)

type **noise** (string noisetype, point p, float t, ...)

1次元（**float**）、2次元（2つの**float**）、3次元（**point**）、4次元（**point**と**float**）のいずれかの領域で定義された連続的で疑似ランダムな（ただし繰り返し可能な）スカラー場を、戻り値となる1次元（**float**）や3次元（**color**、**point**、**vector**、**normal**）のいずれかを用いて返します。
**noisetype**は、様々なノイズ関数の中から使用するものを明示する。
**"perlin"**, "**snoise"**
符号付きパーリン系勾配ノイズで、出力範囲は[−1, 1]、おおよその平均値は0、整数格子点では正確に0になります。これは**snoise()**関数と等価です。
**"uperlin"**, "**noise"**
符号なしパーリン系勾配ノイズで、出力範囲は(0,1)、おおよその平均値は0.5、整数格子点では正確に0.5です。これは noise() 関数（名前文字列をとらないもの）と等価です。
**"cell"**
すべての整数**i**に対して[i, i + 1)の範囲で一定な離散関数（つまり、**cellnoise(x) == cellnoise(floor(x))**）で、すべての整数で無相関で異なる値をとります。その範囲は[0, 1]で、その全体平均は0.5で、それらの値は[0,1]に均等に分布しています。
**"hash"**
実入力座標ごとに無相関で異なる（ただし、決定論的で再現可能な）値を返す関数です。この範囲は[0, 1]で、その全体平均は0.5で、それらの値は[0,1]範囲内で均等に分布しています。
**"simplex"**
出力範囲が[**−1**, **1**]の符号付きシンプレックスノイズで、おおよその平均値は0です。
**"usimplex"**
出力範囲が[**0**, **1**]の符号なしシンプレックスノイズで、おおよその平均値は0.5です。
**"gabor"**
ガボールインパルス関数（Lagae et al., SIGGRAPH 2012参照）に基づく、帯域制限とフィルタリングがされた疎な畳み込みノイズ。このガボールノイズは、パーリンノイズに少し似た周波数成分と範囲（[−1, 1]の範囲で、その全体平均がほぼ0）を持つように設計されています。これは、パーリンノイズと比べてかなり高コストですが、入力微分に基づいて自動的に正しくフィルタリングを行なうというメリットがあります。ガボールノイズでは、noise()コールにいくつかのオプションパラメータを渡すことができます:

**"anisotropic"**, <int>
**"direction"**, <vector>
**anisotropic**が0（デフォルト）の場合、ガボールノイズは等方性になります。**anisotropic**が1の場合、ガボールノイズは**direction**ベクトル（デフォルトは(1,0,0)）で与えられた3次元周波数による異方性となります。**anisotropic**が2の場合、**direction**ベクトルに沿って異方的になり、ベクトルに垂直な半径方向に等方的なハイブリッドモードが使用されます。**anisotropic**が0の場合、**direction**ベクトルは使用されません。
**"bandwidth"**, <float>
ガボールノイズの帯域幅を制御します。デフォルトは1.0です。
**"impulses"**, <float>
ガボールノイズのセルあたりのインパルス(力積)の数を制御します。デフォルトは16です。
**"do\_filter"**, <int>
**do\_filter**が0の場合、フィルタリング/アンチエイリアスは行われません。デフォルトは1です(つまり、フィルタリングされます)。フィルタリングを無効にする妥当な理由は恐らくありませんが、フィルタリングが適切に動作しているかどうかをテストするのが主です。
ノイズの種類によっては、出力範囲が[-1,1]のものもあれば、[0,1]のものもあります。
また、（ルックアップ座標の微分に基づいて）自動的に出力にアンチエイリアスをかけるものもあれば、かけないものもあり、その他さまざまな性質で異なることがあります。ユーザーは、さまざまな状況でどのノイズの種類が役に立つのかを知っておくべきです。

OSLを実装した特定のレンダラーによっては、ここでは説明されていない追加のノイズの種類が提供されていることがあります。

**noise()**関数は、座標の後にオプションの引数をとり、（オプションのテクスチャ引数と同様に）トークン/値のペアとして渡されます。一般的に、このような引数はノイズのタイプに特有であり、対応していないノイズタイプでは無視されます。

type **pnoise** (string noisetype, float u, float uperiod)

type **pnoise** (string noisetype, float u, float v, float uperiod, float vperiod)

type **pnoise** (string noisetype, point p, point pperiod)

type **pnoise** (string noisetype, point p, float t, point pperiod, float tperiod)

周期バージョンの**noise**です。これは、指定した周期でその定義域が繰り返されます。一般的には、整数値の周期のみがサポートされます。
type **noise** (float u)

type **noise** (float u, float v)

type **noise** (point p)

type **noise** (point p, float t)

type **snoise** (float u)

type **snoise** (float u, float v)

type **snoise** (point p)

type **snoise** (point p, float t)

古い**noise(...coords...)**関数は、**noise("uperlin", ...coords...)**と等価で、**snoise(...coords...)**は、**noise("perlin", ...coords...)**と等価です。
type **pnoise** (float u, float uperiod)

type **pnoise** (float u, float v, float uperiod, float vperiod)

type **pnoise** (point p, point pperiod)

type **pnoise** (point p, float t, point pperiod, float tperiod)

type **psnoise** (float u, float uperiod)

type **psnoise** (float u, float v, float uperiod, float vperiod)

type **psnoise** (point p, point pperiod)

type **psnoise** (point p, float t, point pperiod, float tperiod)

古い**pnoise(...coords...)**関数は、**pnoise("uperlin", ...coords...)**と等価で、**psnoise(...coords...)**は**pnoise("perlin", ...coords...)**と等価です。
type **cellnoise** (float u)

type **cellnoise** (float u, float v)

type **cellnoise** (point p)

type **cellnoise** (point p, float t)

古い**cellnoise(...coords...)**関数は、**noise("cell", ...coords...)**と等価です。
type **hashnoise** (float u)

type **hashnoise** (float u, float v)

type **hashnoise** (point p)

type **hashnoise** (point p, float t)

1次元、2次元、3次元、または4次元座標の決定論的で繰り返し可能なハッシュを返します。戻り値は[0,1]上に均等に分布し、同じ座標を再度渡したときに完全に再現可能で、他の位置のハッシュ（近傍の点を含む）とは相関しません。これは、空間的にインデックス付けされたランダムな値を持っているようなものですが、(入力が正確に同一であれば)アニメーションのフレームが変わっても再現可能です。
int **hash** (float u)

int **hash** (float u, float v)

int **hash** (point p)

int **hash** (point p, float t)

int **hash** (int i)

決定論的で再現可能な1-, 2-, 3-, 4-D座標の整数ハッシュを返します。
type **spline** (string basis, float x, type y0, type y1, ... type yn−1)

type **spline** (string basis, float x, type y[ ])

type **spline** (string basis, float x, int nknots, type y[ ])

**x**が0から1に変化すると、**spline**は、均一間隔なノットの

y

0

.
.
.

y

n
−
1

{\displaystyle y\_{0}...y\_{n-1}}

の3次元補間の値を返します。
配列バージョンのコールでは、そのノットは

y
[
0
]
.
.
.
y
[
n
−
1
]

{\displaystyle y[0]...y[n-1]}

(**n**は配列長)で指定し、
ノットの数を明示的に指定するバージョンのコールでは、そのノットは

y
[
0
]
.
.
.
y
[
n
k
n
o
t
s
−
1
]

{\displaystyle y[0]...y[nknots-1]}

(全配列長よりも短くて構いません)で指定します。
入力値**x**は[0, 1]内に収まるようにクランプされます。**type**には**float**, **color**, **point**, **vector**, **normal**のどれかを指定することができます。(例えば**color**のような)複数コンポーネントタイプに関しては、各コンポーネントが別々に補間されます。
補間のタイプは、**basis**名、**basis**パラメータで指定します(**catmull-rom**, **bezier**, **bspline**, **hermite**, **linear**, **constant**のどれか)。いくつかの**basis**タイプには、特定の数のノット値を必要とします。例えば、Bezierスプラインには4n + 3の数を、Hermiteスプラインには4n + 2の数を必要とし、Catmull-RomとLinearのスプラインではn ≥ 4の数を使用することができます。他のスプラインタイプとの整合性を維持できるように、**linear**スプラインは最初と最後のデータ値を無視して、

y
1

{\displaystyle y\_1}

から

y

n
−
2

{\displaystyle y\_{n-2}}

までの区間を線形的に補間し、**constant**スプラインは最初のデータ値と最後の2つのデータ値を無視します。
float **splineinverse** (string basis, float v, float y0, ... float yn−1)

float **splineinverse** (string basis, float v, float y[ ])

float **splineinverse** (string basis, float v, int nknots, float y[ ])

**spline()**関数の**逆関数**を計算します。つまり、**spline (basis, x, y...)**が**v**を返すような**x**値を返します。ノットに単調な値(増加のみ、減少のみ)を指定しなかった場合には、この結果は未定義になります。
**spline**と**splineinverse**を組み合わせることで、横軸が不均一なフルスプラインを計算することができます:

```
    float v = splineinverse (basis, x, nknots, abscissa);
    result = spline (basis, v, nknots, value);

```

### 微分と面積の演算

float **Dx** (float a), **Dy** (float a), **Dz** (float a)

vector **Dx** (point a), **Dy** (point a), **Dz** (point a)

vector **Dx** (vector a), **Dy** (vector a), **Dz** (vector a)

color **Dx** (color a), **Dy** (color a), **Dz** (color a)

2つの主方向である

∂
a

/

∂
x

{\displaystyle \partial a/\partial x}

と

∂
a

/

∂
y

{\displaystyle \partial a/\partial y}

それぞれに対して**a**の偏微分の近似を計算します。レンダラーの実装によっては、それらの方向は、画像平面に平行だったり、オブジェクトのサーフェス上に沿っていたりなどします。
**Dz()**関数はボリュームシェーディングでのみ意味を成し、他のコンテキストでは0が返されます。また、一部のOSL実装では、特定の入力(例えば**P**)に対してのみ"正しい"**Dz**値を返すこともできます。
float **filterwidth** (float x)

vector **filterwidth** (point x)

vector **filterwidth** (vector x)

引数**x**の差分、つまり、隣接シェーディングサンプル間の**x**の近似された変化量を計算します。
float **area** (point p)

**p**位置のシェーディングサンプルに相当するその面積差を返します。**p**が実際のサーフェス位置**P**であれば、**area(P)**は、このシェーディングサンプルで"網羅"されるサーフェス部分の表面積を返します。
vector **calculatenormal** (point p)

サーフェスの向きを考慮して、ポイント**p**(**p**は現在のシェーディングサーフェス上のすべてのポイントで計算されます)で定義されるサーフェスに垂直なベクトルを返します。
float **aastep** (float edge, float s)

float **aastep** (float edge, float s, float ds)

float **aastep** (float edge, float s, float dedge, float ds)

**step(edge,s)**と同様に、アンチエイリアスがかかったステップ関数を計算しますが、**s**と**edge**がサーフェス上で変化する速さを考慮してエッジにフィルターをかけます。差分の**ds**や**dedge**を明示的に指定しなかった場合、それらの差分は(**filterwidth()**を使って)自動的に計算されます。
### ディスプレイスメント関数

void **displace** (float amp)

void **displace** (string space, float amp)

void **displace** (vector offset)

指定した名前の**space**(何も指定しなければ**common**空間)を基準に、**amp**ユニット分だけシェーディング法線**N**の方向にサーフェスを変位させます。別の方法としては、通常の**offset**を使って完全にサーフェスを移動させることができます。この場合、その**offset**はサーフェス法線の方向である必要はありません。
どちらの場合でも、この関数は、サーフェスを変位させ、シェーディング法線**N**をその変位サーフェスの新しいサーフェス法線に調整します(角張ってしまう問題を起こさずに、角張ったジオメトリの法線を補間するだけでなく、連続的に滑らかなサーフェスになるように適切に制御します)。
void **bump** (float amp)

void **bump** (string space, float amp)

void **bump** (vector offset)

サーフェス位置を実際に動かさずに、まるで指定した量でサーフェスが変位しているかのようなサーフェス法線(**displace()**関数の説明を参照)になるようにシェーディング法線**N**を調整します。
### 文字列関数

void **printf** (string fmt, ...)

ほぼC言語と同様に、**printf()**はフォーマット文字列**fmt**と引数リストを受け取って、その結果のフォーマット文字列をコンソールにプリントします。
**fmt**にはC言語の**printf**と同様のフォーマット文字列を指定します。**%d**, **%i**, **%o**, **%x**の引数には**int**の引数を必要とします。**%f**, **%g**, **%e**には**float**, **color**, ポイント系タイプ, **matrix**の引数を必要とします(**color**などの複数コンポーネントタイプに関しては、そのフォーマットは各コンポーネントに適用されます)。**%s**には**string**または**closure**の引数を必要とします。
すべての置換コマンドは、通常のC/C++フォーマット規則に準拠しているので、**%6.2f**などのフォーマットコマンドは期待通りに動作するはずです。
string **format** (string fmt, ...)

**format**関数は**printf**と同様に動作しますが、その結果をプリントするのではなく、そのフォーマットテキストを文字列として返します。
void **error** (string fmt, ...)

void **warning** (string fmt, ...)

**error()**と**warning()**の関数は**printf**と同様に動作しますが、その結果がレンダラーのエラーまたは警告のメッセージとしてプリントされます。さらに、そのシェーダの名前、そのシェーディングされたオブジェクトに関する情報と他の診断情報を含めることができます。
void **fprintf** (string filename, string fmt, ...)

**fprintf()**関数は**printf**と同様に動作しますが、デフォルトのテキスト出力ストリームにプリントせず、その結果は、**filename**に指定されたテキストファイルの最後に連結されます。
string **concat** (string s1, ..., string sN)

文字列のリストを連結して、その結果の文字列を返します。
int **strlen** (string s)

文字列**s**内の文字数を返します。
int **startswith** (string s, string prefix)

文字列**s**が部分文字列**prefix**で始まっていれば1、そうでなければ0を返します。
int **endswith** (string s, string suffix)

文字列**s**が部分文字列**suffix**で終わっていれば1、そうでなければ0を返します。
int **stoi** (string str)

**str**の最初の部分を**int**表現に変換/復元します。これは10進法を想定します。その文字列に目的の型の有効な表現がなければ、戻り値は0になります。
float stof **(string str)**

**str**の最初の部分を**float**表現に変換/復元します。その文字列に目的の型の有効な表現がなければ、戻り値は0になります。
int **split** (string str, output string results[ ], string sep, int maxsplit)

int **split** (string str, output string results[ ], string sep)

int **split** (string str, output string results[ ])

区切り文字列**sep**によって文字列**str**を区切った単語を**result**配列に埋めます。**maxsplit**を指定すれば、最大で**maxsplit**個まで分割されます。**sep**に**を指定した(または何も指定しない)場合、ホワイトスペースの文字列が区切り文字列になります。戻り値は、その**results**配列に書き出された要素(区切られた文字列)の数です。**
string **substr** (string s, int start, int length)

string **substr** (string s, int start)

文字列**s**の**start**番目(0から開始)の文字から始まる最大**length**文字数の文字列を返します。**length**を省略すると、文字列**s**の**start**番目から最後までの文字列を返します。**start**にマイナスの値を指定すると、文字列の最後から数えられます(例えば、**substr(s,-1)**は文字列**s**の最後の文字だけを返します)。
int **getchar** (string s, int n)

文字列**s**のn番目の文字の数値を返します。**n**が有効な文字でなければ0を返します。
int **hash** (string s)

決定的で再現可能な文字列の*ハッシュ*を返します。
int **regex\_search** (string subject, string regex)

int **regex\_search** (string subject, int results[ ], string regex)

**subject**の部分文字列が標準POSIX正規表現**regex**に合致すれば1、合致しなければ0を返します。
**results**配列を指定する形式の関数では、合致すると、以下のようにその配列が充たされます:
results[0] 正規表現に合致したシーケンスの最初の文字インデックス。
results[1] 正規表現に合致したシーケンスの最後の文字インデックス(厳密には、最後に合致した文字インデックスに1を追加)。
results[2i] 正規表現の部分エクスプレッション*i*に合致したシーケンスの最初の文字インデックス。
results[2i + 1] 正規表現の部分エクスプレッション*i*に合致したシーケンスの最後の文字インデックス(厳密には、最後に合致した文字インデックスに1を追加)。
部分エクスプレッションは、正規表現の中で括弧で閉じて表記します。
以下に正規表現の例をいくつか載せています:

```
    regex_search ("foobar.baz", "bar") = 1
    regex_search ("foobar.baz", "bark") = 0

    int match[2];
    regex_search ("foobar.baz", match, "[Oo]{2}") = 1
                                      (match[0] === 1, match[1] === 3)
    substr ("foobar.baz", match[0], match[1]-match[0]) = "oo"

    int match[6];
    regex_search ("foobar.baz", match, "(f[Oo]{2}).*(.az)") = 1

    substr ("foobar.baz", match[0], match[1]-match[0]) = "foobar.baz"
    substr ("foobar.baz", match[2], match[3]-match[2]) = "foo"
    substr ("foobar.baz", match[4], match[5]-match[4]) = "baz"

```

int **regex\_match** (string subject, string regex)

int **regex\_match** (string subject, int results[ ], string regex)

**regex\_search**と同じですが、部分文字列のみに合致すれば良いのではなく、文字列**subject**全体に合致しなければなりません。
### テクスチャ

type **texture** (string filename, float s, float t, ...params...)

type **texture** (string filename, float s, float t,

        float dsdx, float dtdx, float dsdy, float dtdy, ...params...)

2D座標(s,t)の索引によって画像ファイルのテクスチャルックアップ(参照)を実行し、差分値の**dsdx**, **dtdx**, **dsty**, **dtdy**(これらの値を指定しなかった場合には、**s**と**t**から自動的にその値が計算されます)で定義された領域に対してアンチエイリアスをかけます。その結果が割り当てられるタイプが**float**なのか**color**なのかは、そのテクスチャ参照が単一チャンネルなのか3チャンネルなのかで決まります。
**texture()**の挙動を制御するオプションのトークン/値の引数は、2Dルックアップ座標の後に指定することができます:
**blur**, <float>
テクスチャ値を参照した時に追加するブラー(デフォルト: 0)。このブラー量は、テクスチャのサイズに比例します(つまり、カーネルによる0.1ブラーは、テクスチャの全体の幅と高さの10%になります)。
**sblur**と**tblur**のパラメータをそれぞれ使用することで、**s**と**t**の方向でブラー量を別々に指定することができます。
**width**, <float>
差分で定義された(または**s**と**t**の微分によって暗黙的に定義された)フィルターのサイズをスケール(乗算)します。デフォルトは1です。つまり、何もスケールが実行されません。**width**を**0**にすると、事実上テクスチャフィルターが完全に無効になります。
**swidth** と**twidth**のパラメータをそれぞれ使用することで、**s**と**t**の方向で**width**値を別々に指定することができます。
**wrap**, <string>
テクスチャが[0,1]範囲外の座標で**ラップ:繰り返す**方法を指定します。対応しているラップモード: **black**, **periodic**, **clamp**, **mirror**, **default**(これがデフォルトです)。**default**値は、テクスチャファイル自体に指定されているラップモードをレンダラーが使用することを意味します(**default**以外の値は、そのファイルで指定されているラップモードを上書きします)。
**swrap**と**twrap**のパラメータをそれぞれ使用することで、**s**と**t**の方向でラップモードを別々に指定することができます。
**firstchannel**, <int>
テクスチャマップからルックアップ(参照)する最初のチャンネル(デフォルト: 0)。
**subimage**, <int>
**subimage**, <string>
マルチ画像テクスチャファイル内のサブ画像を(数値インデックスまたは名前で)指定します(デフォルト: subimage 0)。
**fill**, <float>
要求されたチャンネルがテクスチャファイル内に存在していない場合にそのチャンネルに対して返される値(デフォルト: 0)。
**missingcolor**, <color>, **missingalpha**, <float>
このパラメータが存在すれば、紛失または破損したテクスチャに対して、それをエラーとして扱わずに、その**代わりとして**使用する紛失カラー(とアルファ値)が指定されます。紛失または破損したテクスチャをエラーとして報告したい場合には、オプションの**missingcolor**パラメータを指定しないでください。
**alpha**, <floatvariable>
指定した変数にアルファチャンネル(これは、**texture()**コールが返すチャンネルの後に続くチャンネルとして扱われます)が格納されます。これによって、**texture()**を一回コールするだけでRGBAルックアップが可能になります。
**errormessage**, <stringvariable>
このオプションを指定すると、テクスチャシステムが吐き出したエラーメッセージは、レンダラーのエラーコールを発動させずに、指定した変数に格納されます。そのため、エラーの処理はシェーダ任せになります。何もエラーが起きなければ、格納されるエラーメッセージは""になります。
**interp**, <string>
テクスチャの補間方法を上書きします: **smartcubic:スマートキュービック**(デフォルト), **cubic:キュービック法**,**linear:線形補間法**, **closest:最近傍法**。
type **texture3d** (string filename, point **p,** ...params...**)**
type **texture3d** (string filename, point **p, vector dpdx, vector dpdy,**
        vector dpdz, **...params...**)

3D座標**p**の索引によってボリュームテクスチャの3Dルックアップを実行し、差分値の**dpdx**, **dpdy**, **dpdz**(これらの値を指定しなかった場合には、**p**から自動的にその値が計算されます)で定義された領域に対してアンチエイリアスをかけます。その結果が割り当てられるタイプが**float**なのか**color**なのかは、そのテクスチャ参照が単一チャンネルなのか3チャンネルなのかで決まります。
**p**座標(**dpdx**, **dpdy**, **dpdz**の差分値が指定されていれば、それらの値も)は、**common**空間にあると想定され、ボリュームファイル自体にトランスフォームが指定されていれば、それらの値がボリュームのローカル座標に自動的に変換されます。
**texture3d()**の挙動を制御するオプションのトークン/値の引数は、3Dルックアップ座標の後に指定することができます:
**blur**, <float>
テクスチャ値を参照した時に追加するブラー(デフォルト: 0)。このブラー量は、テクスチャのサイズに比例します(つまり、カーネルによる0.1ブラーは、テクスチャの全体の幅と高さと奥行きの10%になります)。
**sblur**と**tblur**と**rblur**のパラメータをそれぞれ使用することで、**s**と**t**と**r**の方向でブラー量を別々に指定することができます。
**width**, <float>
差分で定義された(または**s**と**t**と**r**の微分によって暗黙的に定義された)フィルターのサイズをスケール(乗算)します。デフォルトは1です。つまり、何もスケールが実行されません。**width**を**0**にすると、事実上テクスチャフィルターが完全に無効になります。
**swidth** と**twidth**と**rwidth**のパラメータをそれぞれ使用することで、**s**と**t**と**r**の方向で**width**値を別々に指定することができます。
**wrap**, <string>
テクスチャが[0,1]範囲外の座標で**ラップ:繰り返す**方法を指定します。対応しているラップモード: **black**, **periodic**, **clamp**, **mirror**, **default**(これがデフォルトです)。**default**値は、テクスチャファイル自体に指定されているラップモードをレンダラーが使用することを意味します(**default**以外の値は、そのファイルで指定されているラップモードを上書きします)。
**swrap**と**twrap**と**rwrap**のパラメータをそれぞれ使用することで、**s**と**t**と**r**の方向でラップモードを別々に指定することができます。
**firstchannel**, <int>
テクスチャマップからルックアップ(参照)する最初のチャンネル(デフォルト: 0)。
**fill**, <float>
要求されたチャンネルがテクスチャファイル内に存在していない場合にそのチャンネルに対して返される値(デフォルト: 0)。
**missingcolor**, <color>, **missingalpha**, <float>
このパラメータが存在すれば、紛失または破損したテクスチャに対して、それをエラーとして扱わずに、その**代わりとして**使用する紛失カラー(とアルファ値)が指定されます。紛失または破損したテクスチャをエラーとして報告したい場合には、オプションの**missingcolor**パラメータを指定しないでください。
**time**, <float>
ボリュームテクスチャに時間で可変するローカルトランスフォームが指定されている場合に使用する時間の値(デフォルト: 0)。
**alpha**, <floatvariable>
指定した変数にアルファチャンネル(これは、**texture3d()**コールが返すチャンネルの後に続くチャンネルとして扱われます)が格納されます。これによって、**texture3d()**を一回コールするだけでRGBAルックアップが可能になります。
type **environment** (string filename, vector R, ...params...)

type **environment** (string filename, vector R, vector dRdx, vector dRdy, ...params...)

**R**方向の索引によって画像ファイルの環境マップのルックアップを実行し、差分値の**dRdx**, **dRdy**(これらの値を指定しなかった場合には、**R**から自動的にその値が計算されます)で定義された領域に対してアンチエイリアスをかけます。その結果が割り当てられるタイプが**float**なのか**color**なのかは、そのテクスチャ参照が単一チャンネルなのか3チャンネルなのかで決まります。
**environment()**の挙動を制御するオプションのトークン/値の引数は、ルックアップ方向(とオプションの差分値)の後に指定することができます:
**blur**, <float>
テクスチャ値を参照した時に追加するブラー(デフォルト: 0)。このブラー量は、テクスチャのサイズに比例します(つまり、カーネルによる0.1ブラーは、テクスチャの全体の幅と高さの10%になります)。
**sblur**と**tblur**のパラメータをそれぞれ使用することで、**s**と**t**の方向でブラー量を別々に指定することができます。
**width**, <float>
差分で定義された(または**s**と**t**の微分によって暗黙的に定義された)フィルターのサイズをスケール(乗算)します。デフォルトは1です。つまり、何もスケールが実行されません。**width**を**0**にすると、事実上テクスチャフィルターが完全に無効になります。
**swidth** と**twidth**のパラメータをそれぞれ使用することで、**s**と**t**の方向で**width**値を別々に指定することができます。
**firstchannel**, <int>
テクスチャマップからルックアップ(参照)する最初のチャンネル(デフォルト: 0)。
**fill**, <float>
要求されたチャンネルがテクスチャファイル内に存在していない場合にそのチャンネルに対して返される値(デフォルト: 0)。
**missingcolor**, <color>, **missingalpha**, <float>
このパラメータが存在すれば、紛失または破損したテクスチャに対して、それをエラーとして扱わずに、その**代わりとして**使用する紛失カラー(とアルファ値)が指定されます。紛失または破損したテクスチャをエラーとして報告したい場合には、オプションの**missingcolor**パラメータを指定しないでください。
**alpha**, <floatvariable>
指定した変数にアルファチャンネル(これは、**environment()**コールが返すチャンネルの後に続くチャンネルとして扱われます)が格納されます。これによって、**environment()**を一回コールするだけでRGBAルックアップが可能になります。
int **gettextureinfo** (string texturename, string paramname, output type destination)

指定した名前のテクスチャファイルからパラメータを取得します。このファイルが存在していて、指定した名前とタイプに合致したパラメータがあれば、その値が**destination**に格納され、**gettextureinfo**は1を返します。このファイルが存在しない、または合致したパラメータ(そしてタイプ)がなければ、**destination**は変更されず、**gettextureinfo**は0を返します。
認識できる有効なパラメータは、以下のとおりです:

int **pointcloud\_search** (string ptcname, point pos, float radius, int maxpoints, [int sort,] string attr, Type data[], ..., string attrN, Type dataN[] )

指定した名前のポイントクラウドから、指定した**radius**の範囲内にある**pos**に近い**maxpoints**個のポイントを検索し、それらのポイントの指定した名前のアトリビュートの値を指定したデータ配列に格納します。オプションの**sort**パラメータが存在していて、それがゼロ以外の値の場合は、それらの見つかったポイントの順番は**pos**からの距離の近い順で並べ替えられます。そうでない場合は、その結果は**pos**に近い**maxpoints**個のポイントが保証されていても、必ずしも距離で並んでいるわけではありません(この結果の方が、ソートの結果と比べていくつかの実装で高速になります)。戻り値はポイントの数で、その範囲は0(近くに何もポイントも見つからない場合)から**maxpoints**や実際の配列長より少ないです(配列は、実際の配列長よりも多く書き込むことはできません)。
これらのアトリビュート名は以下の名前が予約されています:

 **distance** | float
 **index** | int

指定した名前のポイントクラウドがまだメモリ内に存在しなかった場合は、そのポイントクラウドが作成され、その名前に合致したポイントクラウドがディスクにあれば、そのポイントクラウドがそのディスクから読み込まれて初期化されます。
例:

```
    float r = 3.0;
    point pos[10];
    color col[10];
    int n = pointcloud_search ("particles.ptc", P, r, 10,
                               "position", pos, "color", col);
    printf ("Found %d particles within radius %f of (%p)\n", r, P);
    for (int i = 0; i < n; ++i)
        printf (" position (%f) -> color (%g)\n", pos[i], col[i]);

```

int **pointcloud\_get** (string ptcname, int indices[],int count, string attr, type data[])

ポイントクラウドと**indices[0..count-1]**ポイントリストを渡すと、各ポイントの**attr**の名前のアトリビュートがそれぞれ**data[0..count-1]**に格納されます。成功すれば1、失敗(アトリビュートがデータのタイプに合致しなかった場合、無効なインデックス、不明なポイントクラウドファイルも含む)すれば0を返します。
この関数は、以下の例のように**pointcloud\_search()**と併用することができます:

```
    float r = 3.0;
    int indices[10];
    int n = pointcloud_search ("particles.ptc", P, r, 10, "index", indices);
    float temp[10];
    int ok = pointcloud_get ("particles.ptc", indices, n, "temperature", temp);

```

int **pointcloud\_write** (string ptcname, point pos, string attr1, type data1, ...)

指定した名前のポイントクラウド内の**pos**位置に(**attr1**, **data1**, ..., **attrN**, **dataN**)タプルを保存します。フレームの計算が終了した時にそのポイントクラウドが保存されます。成功すれば1、失敗(アトリビュートがポイントクラウド内の別の位置で名前やタイプが合致しなかった場合も含む)すれば0を返します。
例:

```
    color C = ...;
    int ok = pointcloud_write ("particles.ptc", P, "normal", N, "color", C);

```

### マテリアルクロージャ

**closure color**関数では、その戻り**値**は象徴的表現になっています。これを**output**変数に渡したり、**Ci**に割り当てることで、レンダラーは後でそれを評価して**-I**方向の出射ラディアンスを計算することができます。
ただし、シェーダ自体は、その**closure color**の数値を調べることはできません。

この仕様の意図は、どのレンダラーでも実装ができるように最小限の役立つマテリアルクロージャのセットを提供することです。
これによって、それぞれのレンダラー側で、そのレンダラー固有の動作をするクロージャを追加することができます。
さらに、それぞれのレンダラー側では、標準クロージャにパラメータとコントロールを追加し、そのクロージャの必要最低限の引数の後に、(**texture()**関数のオプション引数と同様に)それらをトークン/値のペアとして渡すことができます。
特定のレンダラーの詳細は、そのドキュメントを参照してください。

#### サーフェスマテリアルクロージャ

closure color **diffuse** (normal N)

滑らかなサーフェスのランバート拡散反射を表現した**closure color**を返します。

∫

Ω

1
π

max
(
0
,
N
⋅
ω
)
C
l
(
P
,
ω
)
d
ω

{\displaystyle \int \_{\Omega }{{\frac {1}{\pi }}\max(0,N\cdot \omega )Cl(P,\omega )d\omega }}

N

{\displaystyle N}

は、

P

{\displaystyle P}

におけるユニット長の正面方向のサーフェス法線です。

Ω

{\displaystyle \Omega}

は、

N

{\displaystyle N}

を基準とした半球状の出射方向すべてのセットです。

C
l
(
P
,
ω
)

{\displaystyle Cl(P,\omega )}

は、

−
ω

{\displaystyle -\omega}

方向に出射する

P

{\displaystyle P}

における入射ラディランスです。
closure color **phong** (normal N, float exponent)

Phong BRDFによるサーフェスのスペキュラー反射を表現した**closure color**を返します。
**exponent**パラメータは、マテリアルの滑らかさを示します(**exponent**値が高いほど表面が滑らかになります)。
closure color **oren\_nayar** (normal N, float sigma)

オーレン・ネイヤー反射式の実装によって粗い表面の拡散反射を表現した**closure color**を返します。**sigma**パラメータは、マテリアルの微細構造の粗さを示します。0は完全に滑らかになり、**diffuse()**と同じ外観になります。
オーレン・ネイヤー反射モデルについては、M. Oren氏とS. K. Nayar氏の**Generalization of Lambert's Reflectance Model**(SIGGRAPH 1994の文献p.239-246(July, 1994))で説明されています。
closure color **ward** (normal N, vector T, float xrough, float yrough)

**P**における表面の異方性スペキュラー反射を表現した**closure color**を返します。**N**と**T**のベクトル(どちらもユニット長と仮定)は、サーフェス法線、接線です。これらのベクトルを使用して、異方性効果のローカル座標系を構築します。**xrough**と**yrough**には、それぞれ接線(**T**)と従法線(**N×T**)の方向の粗さを指定します。
Ward BRDFについては、Ward, G.氏の**Measuring and Modeling Anisotropic Reflection**(SIGGRAPH 1992の文献)で説明されています。
closure color **microfacet** (string distribution, normal N, vector U, float xalpha, float yalpha, float eta, int refract)

**beckmann**や**ggx**のような**microfacet distribution**(微細表面分布)によって表面上の散乱を表現した**closure color**を返します(Walter氏らの**Microfacet Models for Refraction through Rough Surfaces**(Eurographics Symposium on Rendering, 2007)で説明されています)。**xalpha**と**yalpha**はどちらとも表面の微細構造の粗さを制御し、それらの値が異なっていれば異方性にすることができます。異方性の場合では、**U**は**N**に直交したベクトルを方向として指定しなければなりません。これらのアルファ値は、普遍的な粗さの尺度ではなく、その文献に載っている分布のアルファ値が望ましいです。**eta**パラメータは、マテリアルの屈折率で、**refract**は、そのBSDFが反射(0)、屈折(1)、両方(2)のどちらなのかを制御する列挙フラグです。この実装では、粗さが等方性の時または指定したベクトルがゼロの時では**U**は全く関与しません。
対応している**distribution**のリストは、レンダラーによって異なり、対応していない**distribution**を指定した時には、その挙動も変わります。その場合に、エラーを起こすのか、または対応している**distribution**のデフォルトに戻すのかは実装次第です。また、エイリアスの**default**は、どのレンダラーでも**distribution**として動作する**distribution**が望ましいです。
closure color **microfacet** (string distribution, normal N, float alpha, float eta, int refract)

何かしらの**microfacet distribution**(微細表面分布)によって表面上の散乱を表現した**closure color**を返します。これは、前の関数を簡素化した等方性バージョンです。
closure color **reflection** (normal N, float eta)

鮮明な鏡のような表面の反射を表現した**closure color**を返します。反射方向は、入射角に基づいて自動的に計算されます。**eta**パラメータはマテリアルの屈折率です。
**reflection**クロージャは、以下のように実装された挙動をします:

```
        vector R = reflect (I, N);
        return raytrace (R);

```

closure color **refraction** (normal N, float eta)

鮮明なガラスのような表面**背後**のオブジェクトの屈折を表現した**closure color**を返します。**eta**パラメータは、サーフェスの**内側**の媒体の屈折率をサーフェスの**外側**の媒体の屈折率で割った比率です。その**外側**の方向とは、**N**で指定された方向です。屈折方向は、入射角と**eta**に基づいて自動的に計算され、返されるラディアンスは、絶縁体のフレネル係数で自動的にスケールされます。
**refraction**クロージャは、以下のように実装された挙動をします:

```
        float Kr, Kt;
        vector R, T;
        fresnel (I, N, eta, Kr, Kt, R, T);
        return Kt * raytrace (T);

```

closure color **transparent** ( )

光の方向が屈折することなく表面を**通過**した光を表現した**closure color**を返します。
**transparent()**クロージャは、以下のように実装された挙動をします:

```
        return raytrace (I);

```

closure color **translucent** ( )

滑らかな表面のランバート拡散透過を表現した**closure color**を返します。これは、**diffuse()**と非常に似ていますが、表面の**奥**側から光を集めます。
**translucent()**クロージャは、以下のように実装された挙動をします:

```
        return diffuse (-N);

```

#### ボリュームマテリアルクロージャ

closure color **isotropic** ( )

等方性ボリュームマテリアルの散乱を表現した**closure color**を返します。これは、元の方向に関係なく全方向均等に光を散乱します。
closure color **henyey\_greenstein** (float g)

小さな浮遊粒子による指向性ボリューム散乱を表現した**closure color**を返します。**g**パラメータは、範囲が-1から1までの異方性係数です。プラスの値は優勢的な前方散乱を示し、マイナスの値は優勢的な後方散乱を示します。**g = 0**は等方性散乱になります。
closure color **absorption** ( )

何か付加的な光の散乱を表現するのではなく、ボリューム吸収が等方性ボリュームマテリアルの散乱を表現して、元の方向に関係なく全方向均等に光を散乱させるようにレンダラーにシグナルを送る**closure color**を返します。
#### 発光クロージャ

closure color **emission** ( )

グロー(白熱)/発光マテリアルを表現した**closure color**を返します。これをサーフェスシェーダグループのコンテキストでコールすると、光がサーフェス法線を中心軸とした半球全体に放出されます。ボリュームシェーダグループのコンテキストでコールすると、シェーディングポイントを中心に全方向均等に光が放出されます。
**emission**クロージャのウェイトの単位はラディアンス(例えば、

W

⋅

s
r

−
1

⋅

m

−
2

{\displaystyle \mathrm {W} \cdot \mathrm {sr} ^{-1}\cdot \mathrm {m} ^{-2}}

)です。つまり、カメラから直接見える表面には、サーフェスやボリュームに関係なく、最終ピクセルに直接クロージャウェイトが再現されます。
サーフェスに対する**emission**に関しては、**emission()**を**surfacearea()\*M\_PI**で割ってみると、物理サイズに関係なく、光の総合的な発光力(例えば

W

{\displaystyle W}

)を簡単に指定することができます。
closure color **background** ( )

ビュー方向から無限に遠くにある**背景**のラディアンスを表現した**closure color**を返します。この実装はレンダラー固有ですが、HDRI環境マップのルックアップが必要となることが多いです。
#### シグナルクロージャ

closure color **holdout** ( )

何か表面の付加的な光の反射を表現するのではなく、その表面が**ホールドアウトオブジェクト**(このオブジェクトは最終出力では透明になりますが、そのオブジェクトの背後にあるオブジェクトを隠します)であることをレンダラーにシグナルを送る**closure color**を返します。1.0未満のウェイトで**holdout()**クロージャにウェイトを付けることで、**部分ホールドアウト**を指定することができます。
closure color **debug** (string outputname)

何か表面の付加的な光の反射を表現するのではなく、指定した名前の出力(つまり、**AOV**)にクロージャのウェイト(**float**または**color**を指定することができます)を加算するようにレンダラーにシグナルを送る**closure color**を返します。
### レンダラーステート(レンダラー状態)とメッセージの受け渡し

int **getattribute** (string name, output type destination)

int **getattribute** (string name, int arrayindex, output type destination)

int **getattribute** (string object, string name, output type destination)

int **getattribute** (string object, string name, int arrayindex,output type destination)

指定した名前のレンダラーアトリビュートまたは補間ジオメトリ変数の値を取得します。オブジェクトの名前を明示的に指定すると、そのオブジェクトのみが検索されます(**global**はグローバルシーンの範囲のアトリビュートを意味します)。オブジェクト名を指定しない形式の関数、または、オブジェクト名に空っぽの文字列**を指定した場合には、レンダラーはまず最初に現行オブジェクト上のオブジェクト単位のアトリビュート(または、オブジェクトに追加されたその名前の補間変数)を検索してから、それでも何も見つからなければ、グローバルシーンの範囲のアトリビュートを検索します。**
アトリビュートが見つかって、それが**destination**のタイプに変換可能であれば、そのアトリビュートの値が**destination**に格納され、**getattribute**が1を返します。アトリビュートが見つからない、または、そのタイプに変換不可能であれば、**destination**は変更されず、**getattribute**が0を返します。
自動タイプ変換には、OSLソースコード内の割り当てで許可されている変換を含みます: **int** to **float**, **float** to **int**(truncation), **float**(または**int**) to **triple**(値を複製), 何かの**triple** to それ以外の**triple**。さらに、OSLソースコード内の割り当てで許可されていない次の変換は、このコールによって実行することもできます: **float**(または**int**) to **float[2]** (どちらの配列要素にも複製), **float[2]** to **triple**(3番目のコンポーネントを0に設定)。
**arrayindex**パラメータを含んだ形式の関数は、指定した名前の配列の個々のインデックスの要素を取得します。この場合、**name**が配列アトリビュートで、**destination**のタイプがその配列要素のタイプ(配列全体のタイプではありません)で、**arrayindex**の値は、その配列サイズで有効なインデックスでなければなりません。
アトリビュートの種類別に**標準化された**名前を以下のテーブルに載せています。すべてのレンダラーがこれらのアトリビュートに対して同じ名前を使用することが望ましいですが、それらのレンダラーが照会したい付加的なアトリビュートに関しては名前を自由に決めることができます。

テーブル 7.1: 取得可能な標準アトリビュートの名前
 **shader:shadername** | string
 **shader:layername** | string
 **shader:groupname** | string

**getattribute()**関数に指定した**object**と**name**のパラメータが有効なカメラの名前を示してした場合、そのカメラ固有の値が取得されます。何もカメラの名前を指定しなかった場合は、暗黙的にグローバルまたはデフォルトのカメラが指定されます。

void **setmessage** (string name, output type value)

**name**/**value**ペアを、同じオブジェクトに適用されている他のシェーダが後でそのペアを取得できる領域に格納します。このシェーダの呼び出しに適用された同じ名前のメッセージが既に存在していれば、そのメッセージが新しいメッセージに置換されます。**value**メッセージには、構造体を除く、基本的なスカラータイプ、配列、クロージャを指定することができます。
int **getmessage** (string name, output type destination)

int **getmessage** (string source, string name, output type destination)

同じオブジェクトに適用された他のシェーダからメッセージを取得します。指定した名前のメッセージが見つかり、そのタイプが**destination**のタイプに合致すれば、その値が**destination**に格納され、**getmessage()**は1を返します。名前もタイプもメッセージが合致しなければ、**destination**は変更されず、**getmessage()**は0を返します。
**source**を指定することで、そのメッセージの取得先を指定し、以下のどれかの値を取得することができます:
**trace**
最後の**trace**コールで当たったオブジェクトに関するデータを取得します。認識されるデータは以下の内容を含みます:

 **hitdist** | float
 **geom:name** | string
 他

取得できる情報は、トレースされた光線に対してシェーダを実行するべきかどうかを示すオプションの**shade**パラメータに応じて、その光線のトレースのされ方で変わります。**shade**が0だった場合、**グローバル**(**P**, **N**など)、補間頂点変数、シェーダインスタンス値、グラフィック状態アトリビュート(オブジェクト名など)を取得することができます。しかし、シェーダ出力変数または(**setmessage()**を通じて)シェーダで設定されるメッセージを正しく取得する場合には、**shade**は0以外の値でなければなりません。
float **surfacearea** ()

シェーディングされているエリアライトジオメトリの表面積を返します。これは、エリア光源の総ワット数に対してユーザー好みで調整された正しい発光ラディアンスを生成できるように**emission()**と併せて使用してください。この関数の値は、非ライトシェーダでは、あまり役に立ちません。
int **raytype** (string name)

シェーディングされている光線が指定したタイプだった場合は1、そのタイプでなかったり、光線タイプ名がレンダラーで認識できなかった場合は0を返します。
一連の光線タイプ名は、OSLに対応しているレンダラー側でカスタマイズすることができますが、最低でも**camera**, **shadow**, **diffuse**, **glossy**, **reflection**, **refraction**を含めるのが望ましいです。これらのタイプ名は必ずしもお互いに排他的ではありませんが、例外として、カメラ光線は**camera**クラス以外にはしないでください。
int **backfacing** ()

表面がその裏面(または閉じたオブジェクトの**内側**)から**見て**サンプリングされていれば1を返します。**表**または閉じたオブジェクトの**外側**から見てサンプリングされていれば0を返します。
int **isconnected** (type parameter)

引数がシェーダパラメータで、シェーダグループの下位レイヤーに接続されていれば1、引数がシェーダグループの上位レイヤーに接続されてたシェーダ出力パラメータであれば2、下位と上位の両方のレイヤーに接続されていれば3、それ以外は0を返します。OSLの関数引数は必ずに参照として渡されるので、関数パラメータに適用される**isconnected()**は、実際のパラメータとして渡される引数によって異なります。
int **isconstant** (type expr)

ランタイム時(すべてのシェーダグループのパラメータ値とコネクションの値を知っている時)に、エクスプレッションを定数値として単純化できると判断できれば1、そうでなければ0を返します。
これは、主に上級のシェーダ作成者がランタイムの最適化によって定数に単純化されるエクスプレッションがどれなのかを検証するためのデバッグ用です。
### 辞書ルックアップ

int **dict\_find** (string dictionary, string query)
int **dict\_find** (int nodeID, string query)

**query**で辞書内のノードを検索します。**dictionary**は、実際の辞書テキストを含んだ文字列または辞書を含んだファイル名のどれかです。(システムはこれらの違いを簡単に区別することができます。)現在のところ、XML辞書に対応しており、今後は、さらに別のフォーマットにも対応予定です。**query**は**XPath 1.0**構文(または、そこから派生した合理的なサブセット)で表現します。
戻り値は**ノードID**です。これは辞書データ内のノードのハンドルであるOpaque(不透明)型の整数識別子です。0は、**query not found**を意味するための予約されており、-1は、その辞書が無効な構文だった(または、ファイルを読み込みできなかった)ことを示します。この辞書内の2つ以上のノードが**query**に合致した場合、最初に合致した**ノードID**が返され、**dict\_next()**を使用することで次に合致したノードに進めることができます。
辞書文字列を受け取るバージョンの関数は辞書のルートを基準に照会するのに対し、**nodeID**を受け取るバージョンの関数は、**nodeID**で指定されたノードを基準に**query**を単に解釈するだけです。
負荷の多いすべての処理(例えば、ファイルからの辞書の読み込みや辞書の初期解読)は、一度だけ実行され、それ以降のルックアップは、ただ単にデータをコピーするだけなので負荷が少ないです。そのため、**dictionary**文字列は、解読された辞書データベースを保持したキャッシュデータ構造のハッシュとして使用されます。このような実装によって、シーンの背後で個々のノードルックアップやタイプ変換をキャッシュ化することもできます。
int **dict\_next** (int nodeID)

**nodeID**を返した**query**に合致した次のノードのノードIDを返します。**nodeID**がその照会において最後に合致したノードだった場合は0を返します。
int **dict\_value** (int nodeID, string attribname, output type value)

指定した辞書ノードから、指定した名前のアトリビュートを取得します。**attribname**が空っぽの文字列""であれば、そのノード自体の値を取得します。アトリビュートが見つかれば、その値が**value**に格納されて、1を返します。指定したアトリビュートがそのノード上にない場合や、値のタイプが指定した名前のノードのタイプに合致していない場合は、値は変更されずに0が返されます。
タイプ変換は単純です: 任意のタイプを**string**として取得することができます。**int**または**float**として取得したい場合は、その値が単一の整数または浮動小数点値として解読されなければなりません。**point**, **vector**, **normal**, **color**, **matrix**(または任意の配列)として取得したい場合は、その値が、スペースやカンマで区切った正しい個数の値として解読されなければなりません。
int **trace** (point pos, vector dir, ...)

**pos**から**dir**方向へ光線を追跡します。この光線は即座に追跡され、**Ci**クロージャを評価した時に偶発的に光線を追跡するよりも非常に負荷がかかります。しかも、これは例えばシェーダにビュー依存を招いてしまうといったように安易に乱用してしまうことに注意してください。この戻り値は、その光線がすべてのジオメトリを見失なった場合に0、指定した距離の範囲内で光線がどこかに当たれば1になります。
オプションのパラメータ:

 **maxdist** | float
 **shade** | int
 **traceset** | string

光線が当たった最も近いオブジェクトに関する情報は、**getmessage("trace",...)** (セクション7.11)を参照を使用して取得することができます。
この関数の主な目的は、シェーダが近くのジオメトリを**probe:精査**できるようにすることです。例えば、ジオメトリによって隠れる可能性のある投影テクスチャを精査したり、露出したジオメトリをもっと**精査**させたり、他のアンビエントオクルージョンのような効果を作成することができます。
#### その他

int **arraylength** (type A[ ])

参照した配列の長さを返します。これはどのタイプでも構いません。
void **exit** ()

これ以上なにも実行せずにシェーダを抜けます。シェーダのメインボディ内では、これは**return**に相当しますが、関数内では**exit()**はシェーダ全体を抜けるのに対し、**return**は内側の関数を抜けるだけです。