ややこしいUnityの座標系の確認方法

Unityの座標系はとにかくややこしい.いやーとにかくややこしい. UnityとOpenCVを併用したりしてるとややこしさが爆発する. 原因はたぶん,C#とCg/HLSLシェーダのように2つの言語が使われてるし, シェーダでprintfみたいなものがないので直接結果を確認できないし. RenderDocはそもそも使い方が良くわからない.

もちろんUnityのマニュアルもあるし,ちまたに解説ブログもあるけど, 説明が不足していたり,肝心なことが書いてなかったり, 確信をもって実装するには,自分が確信をもって出来るツールでのみで試してみる他ない.

そこで簡単なコードのみで,実際にどのように座標系が設定されて変換されるのかを, マニュアルをあまり見ずに(信用せずに),自分で確認したことを記録しておく.

Unityシェーダでのベクトルと行列の掛け算の仕組み

https://buaiso.blogspot.com/2020/12/unitycg.html

C#(CPU)からシェーダのグローバル変数経由で値が送られて画面上の各画素の色となって出力されるという画面の順を考えると, まずC#からシェーダに行列を送ったときに,どうなるのか知りたくなる. もっと具体的に言うとC#上で行列がどのように格納されていて,シェーダ送られたときにどのような形になっているのか知りたい. ただ,シェーダ上で行列が得られても,その行列の中身を確認するすべがないから,結局画面に出力して色を見るしかない. 行列の要素を取り出す確実な方法が,行列と単位ベクトルを掛け算すること.ということで, まずはシェーダ単体でmul()関数を使って行列とベクトルがどのように掛け算されるのかを確認したのがこの記事.

C#からCgに行列を受け渡すとどうなるのか?

https://buaiso.blogspot.com/2020/12/unitycg_4.html

シェーダ内での行列とベクトルの演算がはっきりしたので, 次はC#からシェーダに行列を渡してみる. C#上でMatrix4x4とVector3を乗算した結果と, シェーダ上でfloat4x4とfloat4をmulで乗算したけっかが同じなら, 行列は転置されることもなく,そのままの形で送られたということ. これを確認する.

UnityObjectToViewPos関数は右手系用?

https://buaiso.blogspot.com/2020/12/unityobjecttoviewpos.html

UnityObjectToViewPos関数は,オブジェクト座標からカメラ座標に変換する関数. 混乱の元はこの関数なんじゃないか?と言っても過言でないくらいこれがややこしい. ブラックボックス化された関数は普段余計なことを考えなくていいぶん, 細かいことしたくなったときは逆に厄介な存在になる典型例かな. CGのマニュアルにはぜひ対応する数式に加えて,座標系を図つきで明記してほしい.

回転行列の右手系⇔左手系変換方法

https://buaiso.blogspot.com/2020/12/blog-post_5.html

一つ前の「 UnityObjectToViewPos関数は右手系用?」を理解するには,右手系と左手系の図的にイメージできるだけじゃなくて, 行列の要素がどのように違うのかを理解していないといけない. この記事,右手系の行列を左手系に変換したらどうなるのか?変換するということはどういうことなのかを,z軸のみを反転する変換で確認してる. 上の記事の中からもリンクを貼っているそこから参照しても問題ない.

Unityのバーテクスシェーダ引数のv.vertexは何座標系?

https://buaiso.blogspot.com/2020/12/unityvvertex.html

ここまでで行列がC#からシェーダにどのように受け渡しされるのかがハッキリしました. ようやくこれを考慮してシェーダを書いていける訳だけど,一抹の不安が... バーテクスシェーダのv.vertexは大丈夫なんだろうか? v.vertexよお前もか?

Unityのフラグメントシェーダ引数のi.vertexって何座標?

https://buaiso.blogspot.com/2020/12/unitycoordinatesystems.html

こうなったらフラグメントシェーダの入力もはっきりさせる. v2fという構造体でバーテスクシェーダからフラグメントシェーダに値の受け渡しが行われる. フラグメントシェーダの入力i.vertexはどうなってんだ?ということでこれも確認してみる.

LoadImage関数で画像がテクスチャ座標上のどこに配置される?

https://buaiso.blogspot.com/2020/12/unitycoordinatesystems.html

こうなったらフラグメントシェーダの入力もはっきりさせる. v2fという構造体でバーテスクシェーダからフラグメントシェーダに値の受け渡しが行われる. フラグメントシェーダの入力i.vertexはどうなってんだ?ということでこれも確認してみる.