イラスト、モデリング、Unity、VR関連

unityとかblenderとかvr関連の作業メモ

ShaderLab 定義済みの値と座標空間とその変換について

++座標空間について

3Dのオブジェクトを画面に映しだすとき、各オブジェクトのローカル空間(座標系)から画面のプロジェクション(クリップ)空間に変換する必要がある。

この変換は

ローカル空間=>ワールド空間=>ビュー空間(カメラ空間)=>プロジェクション(クリップ空間)=>正規化デバイス・ビューポート空間の順に変換される。

 

ローカル空間ー各オブジェクトの原点を中心とした空間

 

ワールド空間ー全てのオブジェクトで共通の原点を持つ空間

 

ビュー空間ーカメラの位置を原点としてカメラが向いている方向をZ軸の負方向(unityでは)とした空間(カメラを原点に移動させ、その分、他のオブジェクトも移動させる)この時点では遠近感がなく、同じサイズのオブジェクトであれば、距離に関係なく同じサイズに見える(視錐台にある限り)

視錐台を理解する - Unity マニュアル

 

プロジェクション空間ー3Dから2Dに変換された空間。

透視投影(遠くにあるものほど小さくする)と並⾏投影(距離に関係なく一定のサイズにする)の2種類がある。xyzがぞれぞれ-1から1に収まる。

zはプラットフォーム依存

Unityではこの差異をGL.GetGPUProjectionMatrix()を使って射影変換行列を補正出来る。

空間とプラットフォームの狭間で - Unityの座標変換にまつわるお話 -

*3Dを2Dに変換するような次元を下げる変換を、射影変換、と呼ぶ 

f:id:arumogina:20190529150350g:plain

f:id:arumogina:20190529150401g:plain

*画像はその7 3Dオブジェクト描画のおさらいから引用

 

プロジェクション変換は、プロジェクションマトリクスを乗算したのちにwで除算することで完了する(このwで除算すると、正規化デバイス・ビューポート空間になる)。このw除算はGPUが暗黙的に行う

具体的には、 GPUは全部の成分をw成分で除算する。

その70 完全ホワイトボックスなパースペクティブ射影変換行列

こちらに詳しい計算式が記述されている。

(パースペクティブ射影変換行列を乗算すると、w成分に変換前のz値が現れる。プロジェクションマトリクス=パースペクティブ射影変換行列、という理解で問題ない・・・はず)

 

これらの変換がオブジェクトに各変換行列を乗算することで行われている。

*これらの一連の変換処理を”レンダリングパイプライン”と呼ぶ

 

Unity - マニュアル: ShaderLab 定義済みの値

定義済みの値は大体は変換行列である

 

補足資料 

Shader プロジェクション変換について - イラスト、モデリング、Unity、VR関連

 

正規化デバイス・ビューポート空間ー

プロジェクションマトリクスを乗算したのちにその時に表れるwで除算した時の空間。

 


++UNITY_MATRIX_V float4x4

現在のビュー行列。

ワールド空間をビュー空間に変換する行列


++UNITY_MATRIX_P float4x4

現在の投影行列

ビュー空間からプロジェクション空間へと変換する。


++UNITY_MATRIX_VP float4x4

現在のビュー行列*射影行列

ワールド空間=>ビュー空間(V)=>プロジェクション空間(P)に変換する 

 

++UNITY_MATRIX_MV float4x4

現在のモデル * ビュー行列。

 ローカル空間=>ワールド空間(M)=>ビュー空間(V)に変換する

 

++UNITY_MATRIX_MVP float4x4

現在のモデル*ビュー*射影行列

オブジェクトのローカル座標をプロジェクション(クリップ)座標に変換するのに使用する行列

mul(UNITY_MATRIX_MVP, v.vertex);

UnityObjectToClipPos();

と同様の結果を得る。 UnityObjectToClipPosの方が高速らしい

*mulは行列の乗算

 

++UNITY_MATRIX_T_MV float4x4

モデル * ビュー行列の転置行列

直行行列を転置すると逆行列が得られます。
そして回転行列は直行行列です。

つまり、回転行列を転置すれば逆行列が得られます。
転置の処理負荷は比較的軽いので、使える場面では積極的に使っていきたい性質です。

逆行列を得るために使うっぽい。

【Unity】ゲームにおける行列の勘所をまとめてみた - LIGHT11

直行行列とは、行列をA、その転置行列をAt,単位行列をIとしたとき

A*At = I

となる行列のことらしい。


++UNITY_MATRIX_IT_MV float4x4

モデル * ビュー行列の逆行列の転置行列

行列Aの転置行列Atの逆行列は、行列Aの逆行列の転置行列

 


UNITY_MATRIX_TEXTURE0 - UNITY_MATRIX_TEXTURE3 float4x4 テクスチャ変換行列


++_Object2World float4x4

現在のモデルマトリックス

ローカル座標をワールド座標に変換するのに使用する行列

mul(unity_ObjectToWorld, v.vertex);

 

多分、仮にUNITY_MATRIX_Mが存在すれば、このObject2Worldが相当する


++_World2Object float4x4

現在のワールド行列の逆

ワールド空間からローカル空間に戻すための行列(多分


++_WorldSpaceCameraPos float3

カメラのワールド空間位置


unity_Scale float4 xyz コンポーネントを使用せず,w が均一に拡大・縮小するスケールを保持しています

 

++座標変換の根本的な仕組みと目的について記述されている

その70 完全ホワイトボックスなパースペクティブ射影変換行列

その7 3Dオブジェクト描画のおさらい

 

++その他の空間

UnityのCameraが使う3つの座標系 - テラシュールブログ

スクリーン座標:サイズが解像度と一致する。左下が原点

ビューポート座標:スクリーン座標のサイズを0〜1にした物

 

++補足

行列A,Bが乗算する場合、Aの列数とBの行数が一致する必要があるので、その計算のために第四引数を付与する場合などがある

mul(unity_WorldToObject,float4(_WorldSpaceCameraPos,1))

 

 

++

ややこしいが、

モデル行列=オブジェクトの中心を原点としたローカル座標の行列

モデルマトリクス=ローカル座標をワールド座標にする変換行列

 

++資料

https://monolizm.com/sab/pdf/%E7%AC%AC%E4%B8%89%E5%9B%9E_%E3%83%97%E3%83%AC%E3%82%BC%E3%83%B3%E8%B3%87%E6%96%99(%E3%81%AA%E3%82%8B%E3%81%BB%E3%81%A93D%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E6%8F%8F%E7%94%BB%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF).pdf

空間とプラットフォームの狭間で - Unityの座標変換にまつわるお話 -

【Unity】MVP行列による座標変換の概念と用語の整理 - LIGHT11

DartでWebGL入門-3D編

GitHub - lettier/3d-game-shaders-for-beginners: 🎮 A step-by-step guide on how to implement SSAO, depth of field, lighting, normal mapping, and more for your 3D game.

Reference Frame以下の図が分かりやすい

3DCGの座標系の紹介 | なたで日記

チュートリアル3:行列