演算子
記号で書く演算子と、後置で作用する swizzle・unpack・スタック操作語をまとめる。 記号演算子にはすべて英字の別名があり、どちらで書いても同じ命令になる。
算術
| 記号 | 別名 | 引数 | クラス | 意味 |
|---|---|---|---|---|
+ |
add |
a b | Ei | a + b |
- |
sub |
a b | Ei | a - b |
* |
mul |
a b | Ei | 成分ごとの積 (内積ではない) |
/ |
div |
a b | Ef | a / b (常に float) |
// |
idiv |
a b | Io | 整数除算。両辺が int でなければ型エラー。b = 0 なら 0 |
% |
mod |
a b | Ei | int なら剰余 (b = 0 なら 0)、float なら fmod (符号は被除数に従う) |
単項マイナスは演算子ではなく関数 neg である (5.1 節)。
比較・論理
| 記号 | 別名 | 引数 | クラス | 意味 |
|---|---|---|---|---|
> |
gt |
a b | Ef | a > b |
< |
lt |
a b | Ef | a < b |
>= |
geq |
a b | Ef | a >= b |
<= |
leq |
a b | Ef | a <= b |
== |
eq |
a b | Ef | a == b (浮動小数の厳密比較) |
!= |
neq |
a b | Ef | a != b |
! |
not |
a | Ef | a == 0 なら 1、そうでなければ 0 |
いずれも成分ごとに評価され、結果は 1.0 / 0.0 からなる同じ型の値になる
(float3 同士の比較は float3 のマスクを返す)。真偽型は存在しないので、
結果はそのまま lerp の重みや乗算のマスクとして使える。
swizzle #…
スタック先頭のベクトルに対する成分抽出・並べ替えを行う後置演算子。
- 成分文字は
xyzw/rgba/uvstの 3 セット。1 つの swizzle 内でセットを混ぜられない (#xgはInvalidSwizzle)。同じ成分の重複は可 (#xxxx)。 - 長さは 1 から 4。結果型は長さ 1 なら
float、それ以外はfloatN。 - 対象がスカラなら
SwizzleOnScalar、対象の次元を超える成分を指すとSwizzleOutOfRange。
unpack ... / unpack
スタック先頭のベクトルを取り除き、その成分を float スカラとして次元数ぶん push する。
vec2 / vec3 / vec4 の逆操作であり、成分ごとに別々の計算をしてから組み直すときに使う。
スカラに適用すると UnpackOnScalar。
スタック操作語
Forth 系と同じ意味論を持つ 5 語。型はコンパイル時に追跡されるため、任意の型に対して使える。
| 語 | 効果 | 必要な深さ |
|---|---|---|
dup |
a → a a |
1 |
drop |
a → |
1 |
swap |
a b → b a |
2 |
over |
a b → a b a |
2 |
rot |
a b c → b c a |
3 |
深さが足りなければ NotEnoughOperands。局所変数がないため、部分式を 2 回使いたいときは
dup、引数順を入れ替えたいときは swap / rot を使う。
演算子の落とし穴
*は成分ごとの積: 内積はdot。/は常に float: 整数除算が必要なら//を使うが、両辺が int でなければ型エラー。- int の 0 除算は例外ではなく 0:
//と int の%は 0 を返す。float の 0 除算は無限大 / NaN。 ==は浮動小数の厳密比較: 誤差を許容するなら- abs EPSILON <のように書く。- ベクトル同士の次元不一致は昇格されない:
float2とfloat3の演算は型エラー。