unity3D数学基础-坐标系、向量、矩阵

3D坐标系与变换:左手VS右手坐标系,从模型到屏幕的转换
本文详细介绍了3D坐标系的左手和右手规则,以及在游戏开发中如Unity中如何进行坐标转换。从模型空间到世界空间,再到观察空间、裁切空间和屏幕空间,每一步变换都有明确的几何意义。此外,还探讨了向量的运算,包括点积和叉积,以及矩阵的乘法、转置和逆矩阵。最后,讨论了线性变换如旋转、缩放和平移在3D空间中的应用。

坐标系

左右手坐标系

  1. 左手坐标系:伸开左手,大拇指指向X轴正方向,食指指向Y轴正方向,其他三个手指指向Z轴正方向。
  2. 右手坐标系:伸开右手,大拇指指向X轴正方向,食指指向Y轴正方向,其他三个手指指向Z轴正方向。
    请添加图片描述请添加图片描述请添加图片描述

3D笛卡尔坐标系:右手坐标系
OpenGL:右手坐标系
Direct3D:左手坐标系
Unity3D:左手坐标系(世界坐标系),即+x, +y, +z分别指向右方,上方和前方。​​​​

各种坐标空间(坐标系)

部分空间种类

  1. 模型空间
  • unity约定:使用的左手坐标系,XYZ分别对应着右上前。
  • 模型空间的原点和坐标轴通常由美术人员在建模软件里确定好的。当导入到unity中,我们可以在顶点着色器中访问到模型的顶点信息,其中包含了每个顶点的坐标,这些坐标都是相对于模型空间中的原点(通常位于模型的重心)定义的。
  • 检视视图中显示的为localPosition的值。
  • transform.localPosition(本地坐标)可以获得物体在父物体的局部坐标系中的位置点。
  1. 世界空间
  • unity约定:使用左手坐标系,但它的XYZ轴是固定不变的。
  • transform.position来获取游戏对象的世界坐标。
  1. 观察空间
  • 右手坐标系,这是符合OpenGL传统的,再这样的观察空间中,摄像机的正前方向指的是-z轴方向。
  • unity约定:摄像机位于原点,+x轴指向右方,+y轴指向上分,而+z轴指向的是摄像机的后方。
  1. 裁切空间
  • 目标是能够方便地对渲染图元进行裁剪:完全位于这块空间内部的图元将会被保留,完全位于这块空间外部的图元将会被剔除,而与这块空间边界相交的图元就会被裁剪。
  • 这块空间是由视椎体来决定。
  1. 屏幕空间
  • 左手坐标系
  • 以像素来定义的,屏幕的左下角为(0,0),右上角为(Screen.width, Screen.height),z轴的坐标是相机的世界坐标中z轴坐标的负值。
  • 屏幕空间是一个二维空间。
  • 鼠标位置坐标属于屏幕坐标,通过Input.mousePosition可以获得该位置的坐标。
  • 手指触摸屏幕也为屏幕坐标,Input.GetTouch(0).position可以获得单个手指触摸屏幕时手指的坐标。
  1. 视口空间
  • 将Game视图的屏幕坐标系单位化
  • 左下角(0,0),右上角(1,1)。z轴的坐标是相机的世界坐标中z轴坐标的负值。

相互空间转换

  1. shader中空间转换
    shader处理流程
  • 模型变换:顶点变换的第一步就是将顶点从模型空间变换到世界空间中。这个变换通常叫做模型变换。注意这里的变换顺序是不能互换的,即先进行缩放,然后进行旋转,最后是平移,然后我们可以构建出模型变换的变换矩阵(因为矩阵不满足交换律,所以不要随便调换变换顺序)
  • 观察变换:顶点变换的第二步,就是将顶点坐标从世界空间变换到观察空间中,这个变换通常叫做观察变换。一种方法是计算观察空间中的三个坐标轴在世界空间下的表示,然后构建出观察空间变换到世界空间的变换矩阵,再对该矩阵求逆得到从世界空间变换到观察空间的变换矩阵。另一种方法是想象平移整个观察空间,让摄像机原点位于世界坐标的原点,坐标轴与世界空间中的坐标轴重合即可
  • 投影变换:顶点变换的第三步,就是将顶点坐标从观察空间变换到裁切空间(也被称为齐次裁剪空间)中,这个变换通常叫做投影变换,这个用于变换的矩阵叫做裁剪矩阵,也被称为投影矩阵。
    • 目的:首先是为投影做准备,真正的投影发生在后面的齐次除法过程中,而经过投影矩阵变换后,顶点的w分量将会有特殊的意义;其次是对x,y,z分量进行缩放。
    • 视椎体指的是空间中的一块区域,这块区域决定了摄像机可以看到的空间。视椎体由两种类型,这涉及两种投影:一种是正交投影,一种是透视投影。
    • 投影:可以理解成一个空间的降维,例如从四维空间投影到三维空间,而投影矩阵实际上并不会真正的进行投影,它会为真正的投影做准备工作。真正的投影会在屏幕映射时发生,通过齐次除法来得到二维坐标。
  • 屏幕映射:就是把顶点从裁剪空间投影到屏幕空间中,来生成对应的2D坐标。在unity中,从裁剪空间到屏幕空间的转换一般是底层帮我们完成的,我们顶点着色器只需要把顶点转换到裁剪空间即可。最后由此通过齐次除法和映射到屏幕。——分为两个步骤:首先进行标准齐次除法,也被称为透视除法。就是用齐次坐标系的w分量去除以x,y,z分量;经过齐次除法后,透视投影和正交投影的视椎体都变换到一个相同的立方体内。接下来可以根据 变换后的x和y坐标来映射输出窗口的对应像素坐标。
  1. unity中C#相关API
  • Transform.forward, Transform.right, Transform.up:当前物体的物体坐标系的z轴,x轴,y轴在世界坐标系上的指向。
  • Transform.TransformPoint(Vector3 position) :将一个坐标点从局部坐标系转换到全局坐标系。
  • Transform.InverseTransformPoint(Vector3 position):将坐标点从全局坐标系转换到局部坐标系。
  • Transform.TransformDirection(Vector3 direction):将一个方向从局部坐标系转换到全局坐标系。
  • Transform.InverseTransformDirection(Vector3 direction):将一个方向从全局坐标系转换到局部坐标系。
  • Transform.TransformVector(Vector3 vector):将一个向量从局部坐标系转换到全局坐标系。
  • Transform.InverseTransformVector(Vector3 vector):将一个向量从全局坐标系转换到局部坐标系。
  • Camera.ScreenToWorldPoint(Vector3 position): 将屏幕坐标转换为全局坐标。
  • Camera.WorldToScreenPoint(Vector3 position):将全局坐标转换为屏幕坐标。
  • Camera.ScreenToViewportPoint(Vector3 position):将屏幕坐标转换为视口坐标。
  • Camera.ViewportToScreenPoint(Vector3 position):将视口坐标转换为屏幕坐标。
  • Camera.WorldToViewportPoint(Vector3 position):将全局坐标转换为视口坐标。
  • Camera.ViewportToWorldPoint(Vector3 position):将视口坐标转换为全局坐标。

向量

认识向量

  • 在数学中,向量(也称为矢量),是指具有大小和方向的量;书写向量时,水平书写的向量叫做行向量
    [ 1 2 3 ] \begin{bmatrix} 1 & 2 & 3 \end{bmatrix} [123]
    垂直书写的向量叫做列向量。
    [ 1 2 3 ] \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix} 123
  • 向量的大小就是向量的长度,也叫做模。向量的方向描述了空间中向量的指向;向量中的数表达了向量在每个维度上的有向位移。
  • 点中的数表示了一个位置,它没有大小、方向的概念;点只有位置,适量只有方向和大小,任何一个点都可以表示成一个从原点出发的矢量。

向量运算

特殊向量

  1. 零向量:大小为0,没有方向的向量,并且它不可以被归一化。
  2. 负向量:向量变负,将得到一个和原向量方向相反、大小相等的向量。
  3. 单位向量:也叫做标准化向量,就是大小为1的向量;对任意的非零向量,我们都可以计算出它的单位向量,即将其归一化(normalization)。单位向量的表示
    a ^ = a ∣ a ∣ \widehat{\bf{a}} =\frac{\bf{a}}{\begin{vmatrix} \bf{a} \end{vmatrix}} a =aa
  4. 在Unity中,可以使用Vector3.Normalize来归一化向量。使用Vector3.normalized来获得归一化后的单位向量;Vector3.Normalize改变当前向量,Vector3.normalized当前向量是不改变的并且返回一个新的规范化的向量。

向量的长度

  1. 即向量的大小,或者向量的模。
  2. 向量的大小就是向量各分量平方和的平方根
  3. 在Unity中,可以通过Vector3.magnitude计算向量的长度。Vector3.sqrMagnitude则返回向量长度的平方;Vector3.Distance(A,B)可以计算2个点A,B之间的距离,即返回向量AB或向量BA的长度。

向量与标量的乘/除法

  1. 向量与标量的乘法,即将向量的每个分量分别与标量相乘。
  2. 向量与非零标量的除法,即乘以该标量的倒数。

向量的加/减法

  1. 只有在两个向量的维度相同时,才可以相加或相减。
  2. 向量的加法和减法,即将向量的各个分量相加或相减。
  3. 向量的加法满足交换律和结合律,向量的减法仅满足结合律。
  4. 几何意义:对于加法,我们可以把矢量a的头连接到矢量b的尾,然后画一条从a的尾到b的头的矢量,来得到a和b相加后的矢量。减法类似
  5. 公式: a ⃗ + b ⃗ = ( a x + b x , a y + b y , a z + b z ) a ⃗ − b ⃗ = ( a x − b x , a y − b y , a z − b z ) \vec{a} + \vec{b}=(a_x+b_x,a_y+b_y,a_z+b_z) \\ \vec{a} - \vec{b}=(a_x-b_x,a_y-b_y,a_z-b_z) a +b =(ax+bx,ay+by,az+bz)a b =(axbx,ayby,azbz)

向量的点积

  1. 也叫做向量的内积。表示如下:其中点不可以省略
    a ⃗ ⋅ b ⃗ \vec{a} \cdot \vec{b} a b
  2. 两种计算公式如下:
    a ⃗ ⋅ b ⃗ = ∣ a ⃗ ∣ ∣ b ⃗ ∣ cos ⁡ θ a ⃗ ⋅ b ⃗ = ( a x b x + a y b y + a z b z ) \vec{a} \cdot \vec{b}=\rvert \vec{a} \rvert \rvert \vec{b} \rvert \cos \theta \\ \vec{a} \cdot \vec{b}=(a_xb_x+a_yb_y+a_zb_z) a b =a b cosθa b =(axbx+ayby+azbz)
  3. 点积满足交换律。
  4. 向量点积的结果是一个标量
  5. 几何意义:
    • 点乘结果描述了两个向量的“相似”程度,点乘结果越大,两向量越相近
    • 投影:向量b在向量a上的投影的长度可以表示为
      ∣ b ⃗ → a ⃗ ∣ = ∣ b ⃗ ∣ cos ⁡ θ = a ⃗ ⋅ b ⃗ ∣ a ⃗ ∣ \begin{vmatrix} \vec{b} \to \vec{a} \end{vmatrix}=\begin{vmatrix} \vec{b} \end{vmatrix} \cos \theta=\frac{\vec{a} \cdot \vec{b}}{\begin{vmatrix} \vec{a} \end{vmatrix}} b a =b cosθ=a a b
  6. 重要性质:
    • 点积可结合标量乘法
      ( k a ⃗ ) ⋅ b ⃗ = a ⃗ ⋅ ( k b ⃗ ) = k ( a ⃗ ⋅ b ⃗ ) (k \vec{a}) \cdot \vec{b} = \vec{a} \cdot (k \vec{b})=k ( \vec{a} \cdot \vec{b}) (ka
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值