Untiy行列まとめ
モデル行列
unity_ObjectToWorld
オブジェクトのTransform行列の逆
Transform行列はunity_WorldToObject
オブジェクトの位置
mul(unity_ObjectToWorld, float4(0, 0, 0, 1))
ビュー行列
View空間とCamera空間は違う
View=正面のzは-1向き(OpenGLコンベンション)
UNITY_MATRIX_V == cam.worldToCameraMatrix
camTrans.position + camTrans.forwardを飛ばすと-1になるはず(多分)
Camera=Unityエンジン側の座標系
unity_WorldToCameraはレンダリングパイプラインにおける現在の""カメラ""なので
シャドウマップレンダリング中は
View=ライトを原点とするView空間から見た空間
Camera=カメラから見た空間
https://gyazo.com/d4ebb768a953dd35ad7aadbdf60e053e
ビュー行列とカメラの位置の関係
https://gyazo.com/bd1fa83d993ba89ac4263c823eca4f1e
code:hlsl
float3 cameraPos = mul(UNITY_MATRIX_I_V, float4(0,0,0,1));
float3 cameraPos2 = UNITY_MATRIX_I_V._m03_m13_m23;
float3 cameraPos3 = _WorldSpaceCameraPos.xyz;
プロジェクション行列
これがわかりやすい
深度
深度バッファに書き込まれてる値は非線形で、0-1か1-0
DirectXの場合はnear to farが1 to 0
depth(z) = f * n / ( (f -n) * z) - n / (f - n)
$ \mathrm{depth}(z) = \frac{fn}{(f-n)z} - \frac{n}{f-n}
zはカメラ座標におけるz(= ビュー座標における-z)
SV_Targetセマンティクスをつけたパラメータはピクセルシェーダーにわたる前に以下を実行する
pos.xyz /= pos.w
pos.wはカメラ座標におけるzが入っている(ビュー行列掛けた後の-z)
pos.xy *= _ScreenParams.xy
解像度をかける
深度をリニアに戻すとき
上の式から逆算するだけ
_ZBufferParamsを使う
code:a
// x = 1-far/near
// y = far/near
// z = x/far
// w = y/far
// or in case of a reversed depth buffer (UNITY_REVERSED_Z is 1)
// x = -1+far/near
// y = 1
// z = x/far
// w = 1/far
float4 _ZBufferParams;