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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 面试题:深拷贝和浅拷贝(超级详细,有内存图)

    面试题:深拷贝和浅拷贝(超级详细,有内存图)这篇文章竟然写了一上午,亲,请怀着感恩的心阅读!!深拷贝和浅拷贝是经常在面试中会出现的,主要考察你对基本类型和引用类型的理解深度。我在无数次的面试中,应聘者还没有一个人能把这个问题回答情况,包括很多机构的培训老师。这篇文章会让你把基本类型和引用类型的区别搞得清清楚楚,搞清楚这两者的区别,你对任何编程语言的都不怕,因为,这不是js一门语言,是任何编程语言中都需要掌握的知识,而…

    2022年10月1日
    2
  • sendfile函数–零拷贝

    sendfile函数–零拷贝零拷贝:零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除通信数据在存储器之间不必要的中间拷贝过程,有效地提高通信效率,是设计高速接口通道、实现高速服务器和路由器的关键技术之一。sendfile#includessize_tsendfile(intout_fd,intin_fd,off_t*offset,size_tcount);参数特别注意

    2022年5月24日
    63
  • boost之timer

    1.timer类实现2.重点说明2.1CLOCKS_PER_SECtimer的计数使用了标准头文件<ctime>里的clock()函数,它返回自进程启动以来的clock计数,每

    2021年12月28日
    41
  • 数组的splice方法和slice方法_splice方法返回值

    数组的splice方法和slice方法_splice方法返回值功能强大的splice方法数组中最强大的方法splice(),可以对数组进行添加、删除、替换操作删除arr=[‘0赵’,‘1钱’,‘2孙’,‘3李’,‘4周’,‘5吴’]arr.splice(index,num)第一个参数表示开始删除的索引位置,num表示删除的个数如arr.splice(1,2)返回的结果为:arr=[‘0赵’,‘3李’,‘4周’,‘5吴’]添加arr=[‘0赵’,‘1钱’,‘2孙’,‘5吴’]arr.splice(index,0,‘x’,‘y’)第一个参数表示

    2022年9月25日
    3
  • 【中英】【吴恩达课后编程作业】Course 4 -卷积神经网络 – 第四周作业

    【中英】【吴恩达课后编程作业】Course 4 -卷积神经网络 – 第四周作业【中文】【吴恩达课后编程作业】Course4-卷积神经网络-第四周作业-人脸识别与神经风格转换

    2022年6月17日
    236
  • Flink入门介绍

    Flink入门介绍

    2021年11月27日
    53

发表回复

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

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