MVP行列
変換後の座標 = P * V * M * 返還前の座標
MVP座標変換の実行場所
MVP変換 (モデル空間からクリップ空間への変換) はシェーダー上で以下のように実装されている
code:UnityShaderUtilities.cginc
inline float4 UnityObjectToClipPos(in float3 pos)
{
#if defined(STEREO_CUBEMAP_RENDER_ON) return UnityObjectToClipPosODS(pos);
// More efficient than computing M*VP matrix product
return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)));
}
カメラ行列の設定個所
code:cs
public static void SetCameraMatrices(CommandBuffer cmd, ref CameraData cameraData, bool setInverseMatrices)
{
#if ENABLE_VR && ENABLE_XR_MODULE if (cameraData.xr.enabled)
{
cameraData.xr.UpdateGPUViewAndProjectionMatrices(cmd, ref cameraData, cameraData.xr.renderTargetIsRenderTexture);
return;
}
Matrix4x4 viewMatrix = cameraData.GetViewMatrix();
Matrix4x4 projectionMatrix = cameraData.GetProjectionMatrix();
// TODO: Investigate why SetViewAndProjectionMatrices is causing y-flip / winding order issue
// for now using cmd.SetViewProjecionMatrices
//SetViewAndProjectionMatrices(cmd, viewMatrix, cameraData.GetDeviceProjectionMatrix(), setInverseMatrices);
cmd.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
if (setInverseMatrices)
{
Matrix4x4 gpuProjectionMatrix = cameraData.GetGPUProjectionMatrix();
Matrix4x4 viewAndProjectionMatrix = gpuProjectionMatrix * viewMatrix;
Matrix4x4 inverseViewMatrix = Matrix4x4.Inverse(viewMatrix);
Matrix4x4 inverseProjectionMatrix = Matrix4x4.Inverse(gpuProjectionMatrix);
Matrix4x4 inverseViewProjection = inverseViewMatrix * inverseProjectionMatrix;
// There's an inconsistency in handedness between unity_matrixV and unity_WorldToCamera
// Unity changes the handedness of unity_WorldToCamera (see Camera::CalculateMatrixShaderProps)
// we will also change it here to avoid breaking existing shaders. (case 1257518)
Matrix4x4 worldToCameraMatrix = Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)) * viewMatrix;
Matrix4x4 cameraToWorldMatrix = worldToCameraMatrix.inverse;
cmd.SetGlobalMatrix(ShaderPropertyId.worldToCameraMatrix, worldToCameraMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.cameraToWorldMatrix, cameraToWorldMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewMatrix, inverseViewMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.inverseProjectionMatrix, inverseProjectionMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewAndProjectionMatrix, inverseViewProjection);
}
// TODO: Add SetPerCameraClippingPlaneProperties here once we are sure it correctly behaves in overlay camera for some time
}
VP行列の設定
VP行列は P * V という順番で乗じている
code:cs
public static void SetViewAndProjectionMatrices(CommandBuffer cmd, Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix, bool setInverseMatrices)
{
Matrix4x4 viewAndProjectionMatrix = projectionMatrix * viewMatrix;
cmd.SetGlobalMatrix(ShaderPropertyId.viewMatrix, viewMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.projectionMatrix, projectionMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.viewAndProjectionMatrix, viewAndProjectionMatrix);
if (setInverseMatrices)
{
Matrix4x4 inverseViewMatrix = Matrix4x4.Inverse(viewMatrix);
Matrix4x4 inverseProjectionMatrix = Matrix4x4.Inverse(projectionMatrix);
Matrix4x4 inverseViewProjection = inverseViewMatrix * inverseProjectionMatrix;
cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewMatrix, inverseViewMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.inverseProjectionMatrix, inverseProjectionMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewAndProjectionMatrix, inverseViewProjection);
}
}