組み込み型
組み込み型の種類
HCSLには以下の基本型が用意されています。
| 型 | 内容 |
|---|---|
| void | |
| int | 整数値 |
| ivec2 | 整数値の2次元ベクトル |
| ivec3 | 整数値の3次元ベクトル |
| ivec4 | 整数値の4次元ベクトル |
| float | 浮動小数点数 |
| vec2 | 浮動小数点数の2次元ベクトル |
| vec3 | 浮動小数点数の3次元ベクトル |
| vec4 | 浮動小数点数の4次元ベクトル |
| mat2 | 浮動小数点数の2x2の行列 |
| mat3 | 浮動小数点数の3x3の行列 |
| mat4 | 浮動小数点数の4x4の行列 |
| bool | 真偽値 |
| sampler2D | 2Dテクスチャ |
| samplerCube | キューブマップ |
加減乗除算
GLSL(HCSL)では、基本型(int, float)やベクトル型、行列型に対して加算(+)、減算(-)、乗算(*)、除算(/)の演算子が使えます。
基本型の演算
float a = 5.0;
float b = 2.0;
float sum = a + b; // 加算(7.0)
float diff = a - b; // 減算(3.0)
float prod = a * b; // 乗算(10.0)
float div = a / b; // 除算(2.5)
ベクトル型の演算
ベクトル同士の演算は、各成分ごとに計算されます。
vec3 v1 = vec3(1.0, 2.0, 3.0);
vec3 v2 = vec3(4.0, 5.0, 6.0);
vec3 sum = v1 + v2; // (5.0, 7.0, 9.0)
vec3 diff = v1 - v2; // (-3.0, -3.0, -3.0)
vec3 prod = v1 * v2; // (4.0, 10.0, 18.0)
vec3 div = v1 / v2; // (0.25, 0.4, 0.5)
vec3 scaled = v1 * 2.0; // (2.0, 4.0, 6.0)
行列型の演算
行列同士の加減算は各要素ごと、乗算は線形代数の行列積になります。
mat3 m1, m2;
mat3 sum = m1 + m2;
mat3 diff = m1 - m2;
mat3 prod = m1 * m2; // 行列積
vec3 v = vec3(1.0, 2.0, 3.0);
vec3 result = m1 * v; // 行列とベクトルの積
注意点
- 型によっては異なる型同士の演算が許可されています(例:
vec4とfloatの乗算など)。ただし、intとfloatなど一部の異なる型同士の演算はエラーになります。演算可能な型の組み合わせ以外では、明示的な型変換が必要です。 - 除算時、0で割ると未定義動作になります。
行列型
HCSLでは、mat2、mat3、mat4 などの行列型をサポートしています。行列は主に座標変換や線形代数演算に利用されます。
行列の宣言と初期化
mat3 m; // 3x3の行列
mat2 custom = mat2(1.0, 2.0, 3.0, 4.0); // 要素を指定して初期化
行列要素へのアクセス・設定
行列の要素は 行列[列][行] の形式でアクセスします(0始まり)。
m[0][1] = 5.0; // 1列2行目の値を設定
m[1] = vec3(1.0, 2.0, 3.0); // 2列目の値をまとめて設定
float v = m[2][0]; // 3列1行目の値を取得
vec3 col = m[2]; // 3列目をまとめて取得
行列の特徴
- HCSLの行列は「右手系・列優先(column-major)」です。
- 行列の各列が連続したメモリ領域に格納されます。
- 例えば
mat3 m;の場合、m[0]は1列目(vec3型)、m[1]は2列目、m[2]は3列目を表します。
- 行列とベクトルの積は
vec3 result = m * v;のように記述します。
サンプル
mat3 m = mat3(1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0);
float a = m[1][2]; // 2列3行目の値(8.0)
m[0][0] = 10.0; // 1列1行目の値を10.0に設定
m[1] = vec3(1.0, 2.0, 3.0); // 2列目の値をまとめて設定
vec3 col = m[2]; // 3列目をまとめて取得
vec3 v = vec3(1.0, 2.0, 3.0);
vec3 r = m * v; // 行列とベクトルの積
ベクトル型
HCSLでは、vec2、vec3、vec4 などのベクトル型を用いて、座標・色・方向など複数の値をまとめて扱うことができます。
ベクトルの宣言と初期化
vec2 st = vec2(0.5, 1.0);
vec4 col = vec3(1.0, 0.5, 0.0, 1.0);
vec4 p = vec4(1.0, 2.0, 3.0, 4.0);
メンバ変数アクセス(スウィズル)
ベクトル型では、各成分に x, y, z, w や r, g, b, a などの名前でアクセスできます。また、複数成分を組み合わせて取得・設定する「スウィズル」も可能です。
なお、xyzwとrgbaはどちらも同じ値を返します。ベクトル演算でrgbaを使っても、カラー演算でxyzwを使っても動作に違いはありません。
用途に応じて、座標や方向を扱う場合はxyzw、色を扱う場合はrgbaを使うことで、コードの意図を分かりやすく表現できます。
Shader言語では、式がベクトル要素の操作なのか色要素の操作なのかを区別しやすくするために、2種類のスウィズル表記が用意されています。
vec4 col = vec3(1.0, 0.5, 0.0, 1.0);
float r = col.x; // 1成分取得
vec2 rg = col.rg; // 2成分取得
col.rgb = vec3(0.2, 0.3, 0.4); // 複数成分まとめて設定
vec2 st = vec2(0.5, 1.0);
float y = st.y; // y成分取得
vec3 rep = st.yyx; // y, y, x の順で新しいvec3を作成
主なアクセスパターン例
col.x,col.y,col.z,col.w(座標や方向)col.r,col.g,col.b,col.a(色)col.xy,col.yz,col.rgbなど(複数成分の取得・設定)st.yyx,col.bgrなど(任意の順で成分を並べ替え)
ベクトル型の演算
ベクトル同士の加算・減算・スカラー倍・内積・外積など、様々な演算が可能です。
vec3 a = vec3(1.0, 2.0, 3.0);
vec3 b = vec3(4.0, 5.0, 6.0);
vec3 sum = a + b;
vec3 scaled = a * 2.0;
float dotVal = dot(a, b); // 内積
vec3 crossVal = cross(a, b); // 外積
配列型
HCSLでは、配列型を使って同じ型の複数の値をまとめて扱うことができます。配列の宣言、初期化、アクセスは以下のように行います。 なお、関数の戻り値として配列を指定することはできません。
配列の宣言
float myArray[5]; // float型の要素を5つ持つ配列
vec4 colors[2]; // vec4型の要素を2つ持つ配列
mat3 matrices[3]; // mat3型の要素を3つ持つ配列
配列の宣言と初期化
宣言と初期化を一緒に行うことができます
float anotherArray[3] = float[3](1.0, 2.0, 3.0);
配列要素へのアクセス
myArray[0] = 10.0;
float value = anotherArray[1];
vec4 color = colors[0];
mat3 m = matrices[2];
配列のインデックスは0から始まります。
struct型
構造体を定義し、それを型として使うこともできます
struct WaveParams
{
float frequency;
float amplitude;
float phaseShift;
};
float wave(vec2 st, WaveParams params)
{
return sin(st.x * params.frequency + params.phaseShift + HEL_TIME) * params.amplitude;
}
void main()
{
・・・
WaveParams params;
params.frequency = 50.0; // 波の周波数
params.amplitude = 1.5; // 波の振幅
params.phaseShift = 20.0; // 波の位相シフト
pos.y += wave(_TexCoord0, params);
・・・
}