/**********
 
  
 * 
 
  
 * 作者 : Quaye
 
  
 * 时间 : 2018.05.21
 
  
 * 
 
  
 * 描述 : 
 
  
 * 坐标空间(Unity中的坐标系):
 
  
 *
 
  
 * 左手 左手 右手 左手 左手
 
  
 * | | | | | 
 
  
 * 模型空间 -> 世界空间 -> 观察空间 -> 剪裁空间 -> 屏幕空间
 
  
 * model world view clip screen
 
  
 * |_____________|_____________|_____________|______________|
 
  
 * | | | |
 
  
 * 模型变换(M) 观察变换(V) 投影变换(P) 屏幕映射
 
  
 * |_____________|_____________|
 
  
 * |
 
  
 * 在顶点着色器中通常串联成一个矩阵MVP
 
  
 *
 
  
 *
 
  
 * 注意 :
 
  
 * 观察空间(Unity中相机空间是右手的 即符合OpenGL传统)
 
  
 * 
 
  
 * 模型空间 <-> 世界空间
 
  
 * 
 
  
 * 模型空间描述:
 
  
 * 假设'模型空间'原点在'世界空间'坐标系下的原点为 O_c,三个坐标轴为 X-c、Y-c、Z-c
 
  
 * 假设'世界空间'原点在'模型空间'坐标系下的原点为 O_w,三个坐标轴为 X-c、Y-c、Z-c
 
  
 * 空间中存在一个点 A,在模型空间中 A 表示为 A_c(X_ac,Y_ac,Z_ac),在世界空间中 A 表示为 A_w
 
  
 * 则存在:
 
  
 * A_w = Matrix_c_w * A_c
 
  
 * A_c = Matrix_w_c * A_w
 
  
 *
 
  
 * 公式推导:
 
  
 * A_w = O_c + X_ac * X-c + Y_ac * Y-c + Z_ac * Z-c
 
  
 *
 
  
 * = (X_o_c,Y_o_c,Z_o_c) + X_ac * (X_x-c,Y_x-c,Z_x-c) + Y_ac * (X_y-c,Y_y-c,Z_y-c) + Z_ac * (X_z-c,Y_z-c,Z_z-c) 
 
  
 *
 
  
 * | X_x-c , X_y-c , X_z-c | | X_ac |
 
  
 * = (X_o_c,Y_o_c,Z_o_c) + | Y_x-c , Y_y-c , Y_z-c | * | Y_ac | 
 
  
 * | Z_x-c , Z_y-c , Z_z-c | | Z_ac |
 
  
 * 
 
  
 * | | | | | | X_ac |
 
  
 * = (X_o_c,Y_o_c,Z_o_c) + | X-c Y-c Z-c | * | Y_ac |
 
  
 * | | | | | | Z_ac |
 
  
 * 
 
  
 * | 1 0 0 X_o_c | | | | | 0 | | X_ac |
 
  
 * = | 0 1 0 Y_o_c | * | X-c Y-c Z-c 0 | * | Y_ac |
 
  
 * | 0 0 1 Z_o_c | | | | | 0 | | Z_ac |
 
  
 * | 0 0 0 1 | | 0 0 0 1 | | 0 |
 
  
 * 
 
  
 * | | | | X_o_c | | X_ac |
 
  
 * = | X-c Y-c Z-c Y_o_c | * | Y_ac |
 
  
 * | | | | Z_o_c | | Z_ac |
 
  
 * | 0 0 0 1 | | 0 |
 
  
 *
 
  
 * | | | | X_o_c | 
 
  
 * = | X-c Y-c Z-c Y_o_c | * A_c
 
  
 * | | | | Z_o_c | 
 
  
 * | 0 0 0 1 | 
 
  
 * 
 
  
 * 因此:
 
  
 * Matrix_c_w = | | | | | |
 
  
 * | X-c Y-c Z-c O_c |
 
  
 * | | | | | |
 
  
 * | 0 0 0 1 |
 
  
 * 
 
  
 * 对于方向适量: 
 
  
 * | | | | | | - X-w - | 
 
  
 * Matrix_c_w = | X-c Y-c Z-c | = Matrix_w_c = | - Y-w - |
 
  
 * | | | | | | - Z-w - | 
 
  
 * 
 
  
 * 世界空间 <-> 观察空间 
 
  
 * 
 
  
 * 方法1:计算观察空间三个坐标轴在世界空间下的表示,从而构建出世界空间到观察空间的变换矩阵
 
  
 * 
 
  
 * 方法2:想象平移整个观察空间,让摄像机原点位于世界坐标的原点,坐标轴与世界坐标轴重合即可
 
  
 * 
 
  
 * 观察空间 -> 剪裁空间 
 
  
 * 
 
  
 * 由观察空间转换到剪裁空间的矩阵叫‘剪裁矩阵’,也被称为‘投影矩阵’ 
 
  
 * 
 
  
 * 透视投影: 
 
  
 * FOV : Field Of View 相机垂直方向的张开角度
 
  
 *
 
  
 * FOV
 
  
 * nearClipPlaneHeight = 2 * Near * tan-----
 
  
 * 2
 
  
 *
 
  
 * FOV
 
  
 * farClipPlaneHeight = 2 * Far * tan-----
 
  
 * 2
 
  
 *
 
  
 * Aspect : 相机横纵比
 
  
 *
 
  
 * nearClipPlanWidth
 
  
 * Aspect = -------------------
 
  
 * nearClipPlanHeight
 
  
 *
 
  
 * arClipPlanWidth
 
  
 * Aspect = -------------------
 
  
 * farClipPlanHeight
 
  
 *
 
  
 *
 
  
 * | FOV |
 
  
 * | cot ---- |
 
  
 * | 2 |
 
  
 * | --------- 0 0 0 |
 
  
 * M-projection = | Aspect | 
 
  
 * | FOV |
 
  
 * | 0 cot ------ 0 0 |
 
  
 * | 2 |
 
  
 * | Far+Near 2*Far*Near |
 
  
 * | 0 0 - -------- - -------- |
 
  
 * | Far-Near Far-Near |
 
  
 * | |
 
  
 * | 0 0 -1 0 |
 
  
 *
 
  
 * 正交投影: 
 
  
 * FOV : Field Of View 相机垂直方向的张开角度
 
  
 *
 
  
 * nearClipPlaneHeiht = 2 * Size
 
  
 *
 
  
 * farClipPlaneHeiht = nearClipPlaneHeiht
 
  
 *
 
  
 * Aspect : 相机横纵比
 
  
 *
 
  
 * nearClipPlanWidth
 
  
 * Aspect = -------------------
 
  
 * nearClipPlanHeight
 
  
 *
 
  
 * arClipPlanWidth
 
  
 * Aspect = -------------------
 
  
 * farClipPlanHeight
 
  
 *
 
  
 * | 1 |
 
  
 * | -------- 0 0 0 |
 
  
 * M-projection = | Aspect | 
 
  
 * | 1 |
 
  
 * | 0 -------- 0 0 |
 
  
 * | Size |
 
  
 * | 2 Far+Near |
 
  
 * | 0 0 - -------- - -------- |
 
  
 * | Far-Near Far-Near |
 
  
 * | |
 
  
 * | 0 0 0 1 |
 
  
 *
 
  
 * 观察空间 -> 剪裁空间 
 
  
 * 
 
  
 * 
 
  
 * Clip_x * pixelWidth pixelHeight
 
  
 * Screenx = -------------------- + -------------
 
  
 * 2 * Clip_w 2 
 
  
 * 
 
  
 * Clip_x * pixelHeight pixelWidth 
 
  
 * Screenx = -------------------- + ------------- 
 
  
 * 2 * Clip_w 2 
 
  
 * 
 
  
 * 
 
  
 *
 
  
 **/
 
  
 
  
using
 
  
using
 
  
using
 
  
 
  
public class Scene_2 : MonoBehaviour
 
  
{
 
  
 
  
void
 
  
 {
 
  
var cube = GameObject.Find("TestCube");
 
  
 
  
"X-c :"+cube.transform.right.ToString("F5"));
 
  
// X-c :(0.43301, 0.86603, 0.25000)
 
  
"Y-c :"+cube.transform.up.ToString("F5"));
 
  
// Y-c :(-0.50000, 0.00000, 0.86603)
 
  
"Z-c :"+cube.transform.forward.ToString("F5"));
 
  
// Z-c :(0.75000, -0.50000, 0.43301)
 
  
"O-c :"+cube.transform.position.ToString("F5"));
 
  
// O-c :(3.00000, 2.00000, 1.00000)
 
  
 Debug.Log(cube.transform.localToWorldMatrix);
 
  
//
 
  
// 0.43301   -0.50000    0.75000  3.00000
 
  
// 0.86603   0.00000  -0.50000    2.00000
 
  
// 0.25000   0.86603  0.43301  1.00000
 
  
// 0.00000   0.00000  0.00000  1.00000
 
  
// 
 
  
// 根据上述输出可验证 M 变换公式,其他公式验证未写
 
  
//
 
  

 
  
//
 
  
// ShaderLab中的变换矩阵如下:
 
  
//
 
  
// UNITY_MATRIX_MVP : 当前的 模型*观察*投影 矩阵,用于将“顶点/方向”时俩从 模型空间 变换到 剪裁空间
 
  
//
 
  
// UNITY_MATRIX_MV : 当前的 模型*观察 矩阵,用于将“顶点/方向”时俩从 模型空间 变换到 观察空间
 
  
//
 
  
// UNITY_MATRIX_V : 当前的 观察 矩阵,用于将“顶点/方向”时俩从 世界空间 变换到 观察空间
 
  
//
 
  
// UNITY_MATRIX_P : 当前的 投影 矩阵,用于将“顶点/方向”时俩从 观察空间 变换到 剪裁空间
 
  
//
 
  
// UNITY_MATRIX_VP : 当前的 观察*投影 矩阵,用于将“顶点/方向”时俩从 世界空间 变换到 剪裁空间
 
  
//
 
  
// UNITY_MATRIX_T_MV : UNITY_MATRIX_MV 的转置矩阵
 
  
//
 
  
// UNITY_MATRIX_IT_MV : UNITY_MATRIX_MV 的逆转置矩阵,用于将“法线”从 模型空间 变换到 观察空间
 
  
//
 
  
// _Object2World : 当前的 模型 矩阵,用于将“顶点/方向”时俩从 模型空间 变换到 世界空间
 
  
//
 
  
// _World2Object : 当前的 模型 矩阵,用于将“顶点/方向”时俩从 世界空间 变换到 模型空间
 
  
//
 
  
 }
 
  
 
  
}