🗻

オブジェクト単位と頂点単位でワールド座標の位置を取得する

2023/04/07に公開

UnityでShaderlabを書いているとよく下記のようなコードを見ます。

o.worldPos = mul(unity_ObjectToWorld, v.vertex);

これは、頂点シェーダーでunity側が用意してくれている変換行列を使用して頂点単位でワールド座標での位置を取得しています。
これをピクセルの色として出力すると、当然ですが頂点によって出力される色が異なります。

では、オブジェクト単位のワールド座標での位置を取得するにはどうしたらよいでしょう?
ここでいうオブジェクト単位のワールド座標での位置というのはInspectorのが画像です。(階層構造がないオブジェクトだとして)

これを実現するために、まずunity_ObjectToWorldの内部を考えます。
この変換行列はモデル行列といってローカルの座標空間からワールド座標空間に変換してくれるものです。
モデル行列をはじめとした変換行列は同次変換行列といわれ、スケール、回転、移動の変換の情報をもっています。
回転とスケールの変換は4x4行列の内、左上の3x3行列に格納されます。
移動は行列の右端である4列目のベクトルに格納されます。

以上のことから、モデル行列の4列目のベクトルはワールド座標での位置(移動)を示していることになります。

そのため、下記のコードでオブジェクト単位でのワールド座標での位置が取得できます

 float3 worldPosition = unity_ObjectToWorld._m03_m13_m23;

これを色で出力した結果は下記の画像です。

位置を(0.5,0,1)にしたので、紫一色になりました。期待通りの挙動だと思います。

最後までお読みいただきありがとうございました。

Discussion