【Unity Shader入门】Shader数学基础:向量(矢量)

【Unity Shader入门】Shader基础概念:渲染流水线
【Unity Shader入门】Shader编程基础:ShaderLab语法
【Unity Shader入门】Shader数学基础:向量(矢量)
【Unity Shader入门】Shader数学基础:矩阵
【Unity Shader入门】Shader数学基础:矩阵变换
【Unity Shader入门】Shader编程初级:Shader结构

Shader数学基础:向量(矢量)

  • 前言
  • 笛卡尔坐标系
    • 二维笛卡尔坐标系
    • 三维笛卡尔坐标系
  • 点和向量
    • 介绍
    • 区别
  • 向量运算
    • 向量和标量的乘法和除法
    • 向量的加法和减法
    • 向量的模
    • 单位向量
    • 向量点积
      • 代数方式
      • 几何方式
      • 几何意义
    • 向量叉积
    • 二维坐标系旋转
    • 二维坐标系平移
    • 二维坐标系旋转和平移

前言

笛卡尔坐标系

二维笛卡尔坐标系

一个二维的笛卡尔坐标系包含了两个部分的信息:
一个特殊的位置,即原点,它是整个坐标系的中心。
两条过原点的互相垂直的矢量,即X轴和Y轴。这些坐标轴也被称为是该坐标的矢量。
OpenGL 和 DirectX 使用了不同的二维笛卡尔坐标系。OpenGL也就是Unity默认的坐标系是以左下角为原点,DirectX是以左上角为原点。如下图:
【Unity Shader入门】Shader数学基础:向量(矢量)_第1张图片

三维笛卡尔坐标系

在三维笛卡尔坐标系中,我们需要定义三个坐标轴和一个原点【Unity Shader入门】Shader数学基础:向量(矢量)_第2张图片
3个坐标轴被称为该坐标系的基矢量,3个坐标轴互相垂直,长度为1,这样的基矢量被称为标准正交基,如果长度不为1,被称为正交基。当然,坐标轴方向也不是固定的,涉及到z轴向里为正还是向外为正,也就有了大家熟知的左手坐标系和右手坐标系。

三维笛卡尔坐标系分为2种不同的坐标系:左手坐标系(left-handed coordinate space)和右手坐标系(right-handed coordinate space)。
【Unity Shader入门】Shader数学基础:向量(矢量)_第3张图片【Unity Shader入门】Shader数学基础:向量(矢量)_第4张图片
Unity使用的是左手坐标系。但对于观察空间来说,Unity使用的是右手坐标系。观察空间,通俗来讲就是以摄像机为原点的坐标系。在这个坐标系中,摄像机的前向是z轴的负方向,这与在模型空间和世界空间中的定义相反。也就是说,z轴坐标的减少意味着场景深度的增加。

点和向量

介绍

点(point):是n维空间(游戏中主要使用二维和三维空间)中的一个位置,它没有大小、宽度这类概念。

向量(vector,也被称为矢量):是指n维空间中一种包含了模(magnitude)和方向(direction)的有向线段。速度(velocity)就是一种典型的向量。向量被用于表示相对于某个点的偏移,也就是说是一个相对量。
向量的模:指的是这个向量的长度。一个向量的长度可以是任意的非负数。
向量的方向:则描述了这个向量在空间中指向。
向量通常由一个箭头表示
向量的头(head):是它的箭头所在的端点处。
向量的尾(tail):是另一个端点处。
只要向量的模和方向保持不变,无论在哪里,都是同一个向量。

标量(scalar):只有模没有方向。例如距离(distance)就是一种标量。

区别

向量可以用于表示相对于另一个点的位置,此时向量的尾是一个位置,那么向量的头就可以表示另一个位置了。如果我们把向量的尾固定在坐标系原点,那么这个向量的表示就和点的表示重合了。尽管点和向量在数学表达式上都是一样的,但区分点和向量之间的不同是非常重要的。可以这样理解,任何一个点都可以表示成一个从原点位置出发的向量。

点:没有大小之分的空间中的位置
向量:有模和方向,但是没有位置的量,相对量(可以描述相对位置),如果向量的头尾都固定在坐标系的原点,则这个向量就和点重合了。

向量运算

向量和标量的乘法和除法

把一个向量和一个标量相乘,意味着对向量进行一个大小为标量的缩放。

k v → = ( k v x , k v y , k v z ) k\overrightarrow v=(k v_x,k v_y,k v_z) kv =(kvx,kvy,kvz)
一个向量也可以被一个非零的标量除。这等同于和这个标量的倒数相乘。

v → k = ( x , y , z ) k = 1 k ( x , y , z ) = ( x k , y k , z k ) , k ≠ 0 \frac {\overrightarrow v}k=\frac{ (x,y,z) } k=\frac 1k (x,y,z)=(\frac xk,\frac yk,\frac zk),k≠0 kv =k(x,y,z)=k1(x,y,z)=(kx,ky,kz),k=0

注意:对于乘法来说,向量和标量的位置可以互换的。但对于除法,只能是向量被标量除,而不能是标量被向量除,这是没有意义的。当k<0时,向量的方向也会取反

例如,如果想把一个向量放大两倍,就乘以2,。当标量小于0时,向量的方向也会相反。

向量的加法和减法

两个向量进行相加或相减,其结果是一个相同维度的新向量。需要注意的是,一个矢量不能和一个标量相加或相减。矢量的加减法遵守三角法则。

a → + b → = ( a x + b x , a y + b y , a z + b z ) \overrightarrow a+\overrightarrow b=(a_x+b_x,a_y+b_y,a_z+b_z) a +b =(ax+bx,ay+by,az+bz)
a → − b → = ( a x − b x , a y − b y , a z − b z ) \overrightarrow a-\overrightarrow b=(a_x-b_x,a_y-b_y,a_z-b_z) a b =(axbx,ayby,azbz)
【Unity Shader入门】Shader数学基础:向量(矢量)_第5张图片

向量的模

向量的模是一个标量,是向量在空间中的长度。对于二维向量,其实就是使用了勾股定理,两个直角边的长度为向量的分量的绝对值,斜边的长度为向量的模。
向 量 a b → 的 大 小 , 也 就 是 向 量 a b → 的 长 度 ( 或 称 模 ) , 记 作 ∣ a b → ∣ 向量\overrightarrow {ab}的大小,也就是向量\overrightarrow {ab}的长度(或称模),记作|\overrightarrow {ab}| ab ab ab
∣ v → ∣ = v x 2 + v y 2 + v z 2 |\overrightarrow v| = \sqrt {v_x^2 + v_y^2 + v_z^2} v =vx2+vy2+vz2

单位向量

很多情况下,我们只关心向量的方向而不是模。比如光照模型中,往往需要知道法线方向和光源方向,这种情况下我们不关心向量有多长,这样就需要计算单位向量。单位向量指的是模为1的向量,也被称为被归一化的向量(normalized vector),而把非零向量转换为单位向量的过程被称为归一化。计算单位向量公式如下:
∣ v ^ ∣ = v ∣ v ∣ , v 是 非 零 向 量 |\hat v|= \frac v {|v|},v是非零向量 v^=vv,v

向量点积

点积有两种定义方式:代数方式和几何方式。通过在欧氏空间中引入笛卡尔坐标系,向量之间的点积既可以由向量坐标的代数运算得出,也可以通过引入两个向量的长度和角度等几何概念来求解。

代数方式

a ⋅ b = ( a x , a y , a z ) ⋅ ( b x , b y , b z ) = a x b x + a y b y + a z b z a \sdot b = (a_x,a_y,a_z) \sdot (b_x,b_y,b_z) = a_xb_x + a_yb_y + a_zb_z ab=(ax,ay,az)(bx,by,bz)=axbx+ayby+azbz
矢量的点积满足交换律:
a ⋅ b = b ⋅ a a \sdot b = b \sdot a ab=ba
点积具有一些很重要的性质,在Shader计算中,我们经常利用这些性质来帮助计算。
性质一:点积可以结合标量乘法,也就是说,对点积中其中一个矢量进行缩放的结果,相当于对最后的点积结果进行缩放,即:
( k a ) ⋅ b = a ⋅ ( k b ) = k ( a ⋅ b ) (ka)\sdot b = a \sdot (kb) = k(a\sdot b) (ka)b=a(kb)=k(ab)
性质二:点积可以结合矢量加法和减法,也就是说,点积的操作数可以是矢量相加或相减后的结果。即:
a ⋅ ( b + c ) = a ⋅ b + a ⋅ c a \sdot (b + c)= a \sdot b + a \sdot c a(b+c)=ab+ac
性质三:一个矢量和本身进行点积的结果,是该矢量的模的平方,这可以用来比较两个矢量的长度大小。
v ⋅ v = v x v x + v y v y + v z v z = ∣ v ∣ 2 v \sdot v= v_xv_x + v_yv_y + v_zv_z = |v|^2 vv=vxvx+vyvy+vzvz=v2

几何方式

a ⋅ b = ∣ a ∣ ∣ b ∣ cos ⁡ θ a \sdot b = |a| |b| \cos \theta ab=abcosθ
两个矢量的点积可以表示为两个矢量的模相乘,再乘以他们之间夹角的余弦值。
利用余弦定理推导:
∣ c ∣ 2 = ∣ a ∣ 2 ∣ b ∣ 2 − 2 ∣ a ∣ ∣ b ∣ cos ⁡ θ |c| ^2= |a|^2 |b|^2 - 2|a| |b| \cos \theta c2=a2b22abcosθ
∣ c ∣ 2 = c ⋅ c = ( a − b ) ⋅ ( a − b ) = a ⋅ a + b ⋅ b − 2 a ⋅ b |c| ^2= c \sdot c = (a-b) \sdot (a-b) = a \sdot a + b \sdot b - 2a \sdot b c2=cc=(ab)(ab)=aa+bb2ab
从这个公式可以看出两个向量的夹角对于点积结果的影响,小于90度为正,等于90度为0,大于90度为负。还可以用反余弦求出两个向量的夹角。
cos ⁡ θ = a ⋅ b ∣ a ∣ ∣ b ∣ \cos \theta = \frac {a \sdot b}{|a| |b|} cosθ=abab
【Unity Shader入门】Shader数学基础:向量(矢量)_第6张图片

几何意义

点积的几何意义中一个重要的几意义是投影(projection),点积的符号可以让我们知道两个矢量的方向关系。
【Unity Shader入门】Shader数学基础:向量(矢量)_第7张图片

向量叉积

叉积在图形学中常用于计算垂直于一个三角面的向量,用于判断三角面片的朝向等。
a ∧ b = ( a x , a y , a z ) ∧ ( b x , b y , b z ) = ( a y b z − a z b y , a z b x − a x b z , a x b y − a y b x ) a\wedge b=(a_x,a_y,a_z)\wedge (b_x,b_y,b_z) =(a_yb_z-a_zb_y,a_zb_x-a_xb_z,a_xb_y-a_yb_x) ab=(ax,ay,az)(bx,by,bz)=aybzazby,azbxaxbz,axbyaybx)
【Unity Shader入门】Shader数学基础:向量(矢量)_第8张图片
三维向量叉积的计算规律。不同颜色的线表示了计算结果向量中对应颜色的分量的计算路径。
以红色为例,即结果向量的第一个分量,它是从第一个向量的y分量出发乘以第二个向量的z分量,再减去第一个向量的z分量和第二向量的y分量的乘积

向量的叉积满足反交换律:
a ∧ b = − b ∧ a a\wedge b=-b\wedge a ab=ba
向量的叉积不满足交换律,也不满足结合律:
a ∧ b   / = b ∧ a a\wedge b \mathrlap{\,/}{=} b \wedge a ab/=ba
( a ∧ b ) ∧ c   / = a ∧ ( b ∧ c ) (a\wedge b) \wedge c \mathrlap{\,/}{=} a \wedge (b \wedge c) (ab)c/=a(bc)

叉积的几何意义:
两个向量叉积会得到一个同时垂直于这两个向量的新向量
∣ a ∧ b ∣ = ∣ a ∣ ∣ b ∣ s i n θ , 其 中 ∣ a ∧ b ∣ 的 值 为 : 以 a 和 b 为 两 边 的 平 行 四 边 形 的 面 积 |a \wedge b|= |a| |b| sin \theta ,其中|a \wedge b|的值为:以a和b为两边的平行四边形的面积 ab=absinθ,ab:ab
【Unity Shader入门】Shader数学基础:向量(矢量)_第9张图片
我们知道两个方向互不平行的向量可以确定一个平面,所以叉积最常见的应用就是计算垂直于一个平面的向量,我们后面会在顶点法线,切线那里用到。

二维坐标系旋转

二维坐标系平移

二维坐标系旋转和平移

你可能感兴趣的:(#,【Unity,Shader入门】,unity,shader,数学基础,向量)