即我们要取得物体身上的一个点P,转换为以摄像机为原点的新坐标P’
观察空间采用右手坐标系
unity中摄像机三个方向轴定义(在右手坐标系中)
z 和摄像机的LookAt方向相反
x 世界空间的 up轴 叉乘 摄像机的z轴
y 摄像机z 叉乘 摄像机x
为了和世界空间的xyz符号区分,我们用uvn表示观察空间的xyz
为了求得P’,我们想办法把点P和摄像机作为一个整体,通过平移,旋转 直到摄像机的uvn轴和世界坐标的xyz轴重合,此时P的坐标既是P’的坐标。
假设摄像机当前位置为eye(eyex, eyey, eyez)。首先平移摄像机到世界坐标原点,需要平移的方向是eye位置的取反值,
[ − e y e x − e y e y − e y e z 1 ] begin{bmatrix} -eyex & -eyey & -eyez & 1 end{bmatrix} [−eyex−eyey−eyez1]
下一步我们需要进行旋转,
根据之前的一篇文章任意物体的旋转矩阵,我们只要乘以以下矩阵,即可使得摄像机的uvn轴和世界坐标的xyz轴重合
[ u x u y u z 0 v x v y v n 0 n x n y n z 0 0 0 0 1 ] begin{bmatrix} ux & uy & uz & 0 \ vx & vy & vn & 0 \ nx & ny & nz & 0 \ 0 & 0 & 0 & 1 end{bmatrix} ⎣⎢⎢⎡uxvxnx0uyvyny0uzvnnz00001⎦⎥⎥⎤
所以有点P乘以上述两矩阵后,即是P‘的位置。
P ′ = [ u x u y u z 0 v x v y v n 0 n x n y n z 0 0 0 0 1 ] . [ 1 0 0 − e y e x 0 1 0 − e y e y 0 0 1 − e y e z 0 0 0 1 ] . [ P x P y P z 1 ] T P'= begin{bmatrix} ux & uy & uz & 0 \ vx & vy & vn & 0 \ nx & ny & nz & 0 \ 0 & 0 & 0 & 1 end{bmatrix}. begin{bmatrix} 1 & 0 & 0 & -eyex \ 0 & 1 & 0 & -eyey \ 0 & 0 & 1 & -eyez \ 0 & 0 & 0 & 1 end{bmatrix}. begin{bmatrix} Px & Py & Pz & 1 end{bmatrix}^T P′=⎣⎢⎢⎡uxvxnx0uyvyny0uzvnnz00001⎦⎥⎥⎤.⎣⎢⎢⎡100001000010−eyex−eyey−eyez1⎦⎥⎥⎤.[PxPyPz1]T
因此顶点从世界空间变换观察空间的变换矩阵M为
M = [ u x u y u z 0 v x v y v n 0 n x n y n z 0 0 0 0 1 ] . [ 1 0 0 − e y e x 0 1 0 − e y e y 0 0 1 − e y e z 0 0 0 1 ] M= begin{bmatrix} ux & uy & uz & 0 \ vx & vy & vn & 0 \ nx & ny & nz & 0 \ 0 & 0 & 0 & 1 end{bmatrix}. begin{bmatrix} 1 & 0 & 0 & -eyex \ 0 & 1 & 0 & -eyey \ 0 & 0 & 1 & -eyez \ 0 & 0 & 0 & 1 end{bmatrix} M=⎣⎢⎢⎡uxvxnx0uyvyny0uzvnnz00001⎦⎥⎥⎤.⎣⎢⎢⎡100001000010−eyex−eyey−eyez1⎦⎥⎥⎤
示例代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Obj2ViewSpace : MonoBehaviour
{public GameObject camera;public GameObject cube;// Start is called before the first frame updatevoid Start(){Vector3 eyePos = ansform.position;// 平移矩阵Matrix4x4 tM = new Matrix4x4(new Vector4(1, 0, 0, -1 * eyePos.x), new Vector4(0, 1, 0, -1 * eyePos.y), new Vector4(0, 0, 1, -1 * eyePos.z), new Vector4(0, 0, 0, 1));// 摄像机的xyz轴Vector3 n = ansform.forward * -1;Vector3 u = Vector3.Cross(Vector3.up, n) * -1;Vector3 v = Vector3.Cross(n, u) * -1;// 旋转矩阵Matrix4x4 rM = new Matrix4x4(new Vector4(u.x, u.y, u.z, 0),new Vector4(v.x, v.y, v.z, 0),new Vector4(n.x, n.y, n.z, 0),new Vector4(0, 0, 0, 1));Matrix4x4 M = rM.transpose * tM.transpose;// 变换后的P的坐标Vector3 viewPos = M.ansform.position);Debug.Log(viewPos);}
}
工程链接
本文发布于:2024-01-29 02:06:59,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170646522411957.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |