Unityシェーダー - float4とは?

C#だと見慣れない float4 って何?

 

調べてみると float4 はベクトル型らしいです。

ベクトル型 (DirectX HLSL)

2 つの部分で構成される単一の名前。1 つめの部分では、スカラー型のいずれかを指定します。2 つ目の部分では、成分の数を指定します。その値は 1 ~ 4 の範囲内である必要があります。

つまり、float4は、floatというスカラー型に成分の数(4)を付加したベクトル型ってことみたい。

 

宣言は

float4 fVector = { 0.2f, 0.3f, 0.4f, 1.0f };

でも

vector <float, 4> fVector = { 1.0f, 0.3f, 0.4f, 1.0f };

でもいいらしい(後者は書かないだろうけど)

 

あと、初期化は

float4 fVector = { 0.2f, 0.3f, 0.4f, 1.0f };

でもいいし、

float4 fVector = float4(1.0f, 0.5f, 1.0f, 1.0f);

とも書けるらしい。ちなみに、C#の勢いで new float4 って書くとエラーでした。

 

あと、ベクトル型へのアクセスは、xyzwだけじゃなく、rgbaでもアクセスできるらしい。独特ですねー

float4 data = float4(1.0f, 0.5f, 0.0f, 1.0f);

 

// result1 と result2 は同じ結果になる
float4 result1 = float4(data.x, data.y, data.z, data.w);
float4 result2 = float4(data.r, data.g, data.b, data.a);

 

あとは抜き出したい成分だけを連続で順序も自由に記述できる。これは便利。C#にもあればいいのに。

float4 pos = float4(1,2,3,4);

float2 f_2D;

f_2D = pos.xy; // float2(1, 2)と同じ

f_2D = pos.xz; // float2(1, 3)と同じ

f_2D = pos.zx; // float2(3, 1)と同じ

f_2D = pos.xx; // float2(1, 1)と同じ

あとはこんなのも書けるらしい。

float2 p;
p.xy = 0;

こう書くと 変数 p の x と y の両方に同時に 0 を入れることができるっぽい。C#的には xy という変数に 0 を代入してるようにしか見えないですね・・・

 

こんなこともできるみたい

float4 pos = float4(1,2,3,4);

float4 f_4D;

f_4D = pos; // float4(1,2,3,4)と同じ

f_4D.xz = pos.xz; // float4(1,0,3,0)と同じ

f_4D.zx = pos.xz; // float4(3,0,1,0)と同じ

 

あ、こんなのもある

f_4D.xyzw = pos.w; // float4(3,3,3,3)と同じ

 

ここからは推測だけど、↑がありなら

f_4D.xyzw = 3;

と書くこともできて、

f_4D = 3;

とxyzwを省略して書くこともできるってことじゃないだろうか・・?

 

つまり、仮に関数の戻り値の型がfloat4であってもfloatで省略して返すことができ、 float値がxyzwに代入されたfloat4を返してるの同義なんじゃないだろうか。

 

Unity の シェーダー言語 のベースとなる HLSL 言語では、基本的な文法はC/C++に準ずるが、グラフィックスプログラムを記述するのに適した専用のベクトル・行列型や関数を備えているそうで、C#しかやってない私のような人には見慣れないものが多いですね。