Unity3d 空间变换中齐次矩阵的w小秘密
2017-11-30 11:03
1511 查看
1.使用变换齐次矩阵与某个齐次坐标相乘得到的结果.
2.使用结果中的w分量,进行齐次除法得到归一化后的齐次坐标.
3.用变换齐次矩阵的逆矩阵与归一化后的齐次坐标相乘(注意我们是用归一化后的齐次坐标,不是上面第一步变换后的齐次坐标),的到还原后的齐次矩阵,其w分量将会有一个特殊的值.
4.如果将还原后的齐次矩阵使用其w分量进行齐次除法,将得到我们最开始用于变换的齐次坐标,彻底还原还原
代数式表示为:
M*V=>V/V.w=V"
M逆*V"=V"/V".w=V
具体为何会有如此结果,尚不清楚,但是Unity中广泛的应用了次齐次矩阵此种特性,特别是在Fragment的空间还原方法上
测试代码如下
2.使用结果中的w分量,进行齐次除法得到归一化后的齐次坐标.
3.用变换齐次矩阵的逆矩阵与归一化后的齐次坐标相乘(注意我们是用归一化后的齐次坐标,不是上面第一步变换后的齐次坐标),的到还原后的齐次矩阵,其w分量将会有一个特殊的值.
4.如果将还原后的齐次矩阵使用其w分量进行齐次除法,将得到我们最开始用于变换的齐次坐标,彻底还原还原
代数式表示为:
M*V=>V/V.w=V"
M逆*V"=V"/V".w=V
具体为何会有如此结果,尚不清楚,但是Unity中广泛的应用了次齐次矩阵此种特性,特别是在Fragment的空间还原方法上
测试代码如下
public class NDC_Position : MonoBehaviour { bool m_isShow = false; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (!m_isShow) { m_isShow = true; //直接使用世界坐标,这样可以方便测试 //建立世界空间到clip空间的变换矩阵 Matrix4x4 _vp = Camera.main.projectionMatrix * Camera.main.worldToCameraMatrix; //建立clip空间到世界空间的逆矩阵 Matrix4x4 _vpInverse = _vp.inverse; Debug.Log("Camera.main.worldToCameraMatrix----\r\n" + _vp.ToString() + "\r\n-------------------------"); Debug.Log("Camera.main.projectionMatrix----\r\n" + Camera.main.projectionMatrix.ToString()+"\r\n-------------------------"); Debug.Log("_vp----\r\n" + _vp.ToString() + "\r\n-------------------------"); Debug.Log("_vpInverse----\r\n" + _vpInverse.ToString() + "\r\n-------------------------"); //手动使用齐次坐标来变换,已查看变换后的w分量 Vector4 _ClipPos = _vp*(new Vector4(transform.position.x, transform.position.y, transform.position.z,1)); Debug.Log("齐次 _ClipPos4=" + _ClipPos.x.ToString() + "," + _ClipPos.y.ToString() + "," + _ClipPos.z.ToString()+","+ _ClipPos.w.ToString() + "=>" + _ClipPos.ToString()); //直接使用非齐次坐标,这样unity3d会自动帮你转换成齐次坐标,变换后自动帮你做齐次除法,最终得到NDC坐标 Vector3 _NDCPos = _vp.MultiplyPoint(transform.position); //因为只返回前三个坐标,所以已经做了齐次除法处理,结果是直接返回了NDC坐标 Debug.Log("齐次除后 _ClipPos=" + _NDCPos.x.ToString()+","+ _NDCPos.y.ToString()+","+ _NDCPos.z.ToString()+"=>"+ _NDCPos.ToString()); //使用clip空间齐次坐标还原 Vector4 _worldPos4 = _vpInverse * (new Vector4(_ClipPos.x, _ClipPos.y, _ClipPos.z, _ClipPos.w)); Debug.Log("齐次还原 _worldPos4=[" + _ClipPos.x.ToString() + ", " + _ClipPos.y.ToString() + ", " + _ClipPos.z.ToString() +", "+ _ClipPos.w.ToString()+ ", 1]=>" + _worldPos4.x.ToString() + ", " + _worldPos4.y.ToString() + ", " + _worldPos4.z.ToString() + ", " + _worldPos4.w.ToString()+"=>"+ _worldPos4.ToString()); //直接使用NDC齐次坐标还原,已查看变换后的w分量 Vector4 _worldPos3 = _vpInverse * (new Vector4(_NDCPos.x, _NDCPos.y, _NDCPos.z,1)); Debug.Log("非齐次还原 _worldPos3=[" + _NDCPos.x.ToString() + ", "+ _NDCPos.y.ToString() + ", "+ _NDCPos.z.ToString()+", 1]=>" + _worldPos3.x.ToString() + ", " + _worldPos3.y.ToString() + ", " + _worldPos3.z.ToString() + ", " + _worldPos3.w.ToString() + "=>" + _worldPos3.ToString()); //Unity3d自动使用NDC齐次坐标还原,返回已经进行了齐次除法后的结果 Vector3 _worldPos = _vpInverse.MultiplyPoint(_NDCPos); Debug.Log("非齐次还原 _worldPos=" + _worldPos.x.ToString() + ", " + _worldPos.y.ToString() + ", " + _worldPos.z.ToString()+"=>" + _worldPos.ToString()); } } }
相关文章推荐
- “生动”讲解——矩阵的空间变换
- “生动”讲解——矩阵的空间变换
- 8.6.3 矩阵与空间变换
- 空间坐标变换的矩阵表示法
- “生动”讲解——矩阵的空间变换
- Unity3D - Shader - 矩阵和变换
- Unity Shader入门精要笔记(四):矩阵与空间变换
- D3D空间变换和矩阵作用
- OpenGL 的空间变换(上):矩阵在空间几何中的应用
- Unity3D - Shader - 坐标空间变换
- DirectX投影变换矩阵的原理与推导,齐次裁剪空间的应用举例
- 齐次空间 放射变换
- 渲染流水线-透视投影矩阵 透视除法 空间裁剪 视口变换 数学原理理解
- “生动”讲解——矩阵的空间变换
- 矩阵的空间变换
- 关于 法向量 的世界空间变换矩阵
- 颜色空间变换(RGB-HSV)
- 蓝以中老师《高等代数》第02章:向量空间与矩阵,笔记
- RenderTransform特效【五种基本变换】及【矩阵变换MatrixTransform】
- 线性代数的本质--对线性空间、向量和矩阵的直觉描述