Unity Shader学习一:矢量的点积和叉积

Unity Shader学习一:矢量的点积和叉积矢量的点积点积的名称来源于这个运算的符号 a b 中间这个圆点符号是不可省略的 在 UnityShader 中 可以直接使用形如 dot a b 的代码来对两个矢量进行点积的运算 点积的公式由两种形式第一种 两个三维矢量的点积是把两个矢量对应分量相乘然后再取和 最后的结果是一个标量 公式为 a b ax ay az bx by bz axbx ayby azbz 矢量的点积满足交换律 即 a b b a 点积的几何意义很重要 因为点积几乎应用到了图形学的各个

矢量的点积

点积(也叫内积)的名称来源于这个运算的符号:a•b。中间这个圆点符号是不可省略的,在Unity Shader中,可以直接使用形如dot(a,b)的代码来对两个矢量进行点积 的运算。

点积的公式由两种形式

第一种:两个三维矢量的点积是把两个矢量对应分量相乘然后再取和,最后的结果是一个标量, 公式为:a•b = (ax, ay, az)•(bx, by, bz) = axbx + ayby + azbz

矢量的点积满足交换律,即a•b = b•a

点积的几何意义很重要,因为点积几乎应用到了图形学的各个方面,其中一个几何意义就是投影    

需要注意的是,投影的值可能是负值,投影结果的正负号与a和b的方向有关:当他们的方向相反(夹角大于90)时,结果小于0;当他们的方向互相垂直(夹角为90)时,结果等于0;当他们的方向相同(夹角小于90)时,结果大于0。也就是说,点积的符号可以让我们知道两个矢量的方向关系。

任何两个矢量的点积a•b等同于a在b方向上的投影值再乘以b的长度,也等同于b再a的方向上的投影值再乘以a的长度。

点积具有一些重要的性质,再Shader的计算中,我们经常会利用这些性质来帮助计算。

性质一:点积可结合标量乘法,公式为:(ka)•b = a•(kb) = k(a•b),也就是说对点积中一个矢量进行缩放,相当于对最后的点积结果进行缩放。

性质二:点积可结合矢量加法和减法,公式为:a•(b + c) = a•b + a•c

性质三:一个矢量和本身进行点积的结果,是该矢量的模的平方,公式为:

v•v = vxvx + vyvy + vzvz = |v|²

第二种:从三角代数的角度出发,可以明确地强调出两个矢量之间的角度

公式为:a•b = |a||b|cosθ

以两个单位向量来看^a•^b = 三角形临边 / 三角形斜边 = cosθ,其中三角形临边为^a•^b,斜边为|b|=1

然后由性质一可得:a•b = (|a|^a)•(|b|^b) = |a||b|(^a•^b) = |a||b|cosθ

利用这个公式,可以求得两个矢量的夹角(再0~180之间) θ = arcos(^a•^b),arcos为反余弦操作。

矢量的叉积

矢量的叉积也叫外积,矢量的叉积仍是一个矢量,与点积类似,叉积的名称来源于它的符号:axb

叉号不可省略,两个矢量的叉积计算公式为:

a x b = (ax, ay, az) x (bx, by, bz) = (aybz – azby, azbx – axbz, axby – aybx)

需要注意的是叉积不满足交换律,即a x b ≠ b x a,但是它满足反交换律,即a x b = -(b x a),而且叉积也不满足结合律,即(a x b) x c ≠ a x (b x c)

对两个矢量进行叉积的结果会得到一个同时垂直与这两个矢量的新矢量,新矢量的模(即a x b 的模)等于a的模乘以b的模再乘以他们夹角的正弦值,公式为|a x b| = |a||b|sinθ 该公式与平行四边形的面积公式相同。

推导过程:以a和b为平行四边形的两条边,所以平行四边形的面积=|b|h (h为b边上的高),而h等于|a|乘以sinθ,所以面积 = |b|h = |b||a|sinθ = |a x b|,

若a与b平行(同向或反向),则a x b = 0,(此处的0为零向量,不是标量0)

接下来来看新矢量的方向,这里需要结合左手坐标系和右手坐标系,在右手坐标系中,a x b 的方向使用右手法则来判断,首先将右手的掌心朝向矢量a的方向,然后弯曲四指让其向b矢量的方向靠拢,此时伸直大拇指,大拇指的方向就是新矢量的方向,在左手坐标系中的判断方法同理。

需要注意的是,在左手/右手坐标系中看似a x b的结果不同,但实际上从公式方面来看,结果是一致的,左手/右手坐标系的选择影响的是在三维空间中的视觉效果,如在unity中将左手坐标系换为右手坐标系会发现图像反了。

叉积常用于计算垂直于一个平面、三角形的矢量,还能用于判断三角面片的朝向

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232619.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号