/**********
*
* 作者 : 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 System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Scene_2 : MonoBehaviour
{
void Start()
{
var cube = GameObject.Find("TestCube");
Debug.Log("X-c :"+cube.transform.right.ToString("F5"));
// X-c :(0.43301, 0.86603, 0.25000)
Debug.Log("Y-c :"+cube.transform.up.ToString("F5"));
// Y-c :(-0.50000, 0.00000, 0.86603)
Debug.Log("Z-c :"+cube.transform.forward.ToString("F5"));
// Z-c :(0.75000, -0.50000, 0.43301)
Debug.Log("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 : 当前的 模型 矩阵,用于将“顶点/方向”时俩从 世界空间 变换到 模型空间
//
}
}