Shader学习(9)法线和切线空间的定义和变换演示
不如醉里风吹尽,又是一天未学习。西山日下雨足稀,又是一周未学习。垂死病中惊坐起,又是一月未学习
最近迷上了骑砍,游戏一玩啥都不管,做什么事都意兴阑珊。
一、法线的概念
三维模型是用一个一个的点构成的,在前面的各种空间变换中,对顶点的位置信息进行了各种计算,但是要想构成一个模型光知道顶点的位置信息是不够的,有一个问题就是,如果我们用几个点构成了一个平面之后,我们该怎么确定哪一面是平面的正面?
法线就是为了确定模型的正面是朝向哪里而存在的。法线(normal)是定义一个点的朝向的信息,它是一个矢量信息,所以也被称为法矢量(normal vector)。当我们变换一个模型的时候,也必须要变换模型的顶点法线,用来在后续的渲染步骤中计算光照,法线可以说是shader中最重要的信息之一,法线出错会导致各种奇怪的显示问题。而如果利用好法线,则可以在shader中实现各种炫酷的效果。
在大部分建模软件当中都可以调出模型的法线信息查看,法线在maya中的显示效果如下:
模型上那些像刺猬一样的线就是顶点法线的显示。
法线有一个特殊的空间为切线空间,切线矢量(tangent vector)也是顶点带有的一个信息。构成一个三维坐标空间的要素是原点和三个互相垂直的矢量。每个顶点有其自身的切线空间,也就是说每个顶点都是自身切线空间的原点,而法线这个矢量就是它的切线空间的Z轴。它的X轴和Y轴是怎么定义的?
在理解切线空间之前必须先理解一下纹理空间,如果想要把一张图片贴到3D模型上面,就必须要把模型的每个位置对应到图片上,等于是把一个物体的皮扒下来展平在图片上。这个图片所在的空间就是纹理空间,纹理空间是一个二维空间,每一个三维模型的顶点都在纹理空间有一个确定的坐标。
在切线空间中,原点就是顶点本身,Z轴就是顶点的法线,X轴和Y轴就是Z轴的两条切线,但是Z轴的切线其实是有无数条的,要如何确定我们要的切线是哪两根切线?一般来说切线空间的Y轴要和纹理空间的Y轴对齐,如上图。而X轴则是由已知的Z轴和Y轴的叉积求出的。
上图示意了当三维模型的UV映射在纹理空间出现变化之后,模型每个点的切线如何变化。
二、法线的变换
一般来说,一个坐标空间下的点可以用同一个4x4变换矩阵变换到另一个坐标空间,一个坐标空间下的绝大部分方向矢量都可以用同一个3x3的变换矩阵来变换坐标空间。比如模型的一个轴向是一个矢量信息,而一个平行光的光照方向也是一个矢量信息,这两个信息在从世界空间变换到摄像机空间的时候,就可以使用同一个变换矩阵来变换。很多时候点和矢量的变换矩阵是相同的,只是点收到平移影响,所以使用4x4变换矩阵,而矢量只需要3x3变换矩阵。对点和切线进行变换时使用的就是同一个矩阵,但是在变换法线的时候则不能和顶点使用同一个矩阵,因为有可能会破坏法线的垂直性。
我们对法线的要求是不论处于任何空间之时,它必须与模型表面垂直,不能随便乱指。空间坐标的变换矩阵影响力就太强,除了平移旋转还有缩放,用过的人都觉得很伤。变换空间时如果是统一缩放,那么最后的效果一切正常,如果有一个轴不能坚定立场,整个模型就像是放错了地方。
此处祭出法宝书,借一张图示意这个效果。
可见空间变换矩阵不仅拉长了你的点,还拉长了你的边。就算是一条矢量,也要把你拉长。
与顶点相同的变换矩阵不能用,吓得我这个学渣不敢动,推导真正的法线变换矩阵的过程知识量太重,越看觉得越发头痛。首先,在坐标空间A中一个点a的法线Na必须要和切线Ta垂直,所以Na和Ta点积的结果为0 。给定点a从坐标空间A变换到坐标空间B的变换矩阵M a->b ,我们已经知道点a的切线Ta和点a使用同一个变换矩阵,所以Ta和M a->b 进行叉积得到在坐标空间B中的切线T b 。
有了坐标空间B中的切线T b以后,就可以找出和T b 的叉积为0(也就是互相垂直)的法线Nb了。
我们想要找到一个矩阵G来直接变换法线Na ,要求得出的结果就是那个和切线T b相垂直的N b 。这个式子可以写成:
在矩阵乘法中有这样一条定律:a·b=(a^T)* b,这里的a^T指示矩阵a的转置。所以有:
又因为定律:
所以:
再根据矩阵乘法的结合律,可以得出:
再根据:“a·b=(a^T)* b,这里的a^T指示矩阵a的转置。”可以得出:
因为Ta 和Na的点积结果为0 ,所以上面式子中的(M a->b ^T ) *G = I 。
根据上面的推导,可以得出结论:使用原变换矩阵的逆转置矩阵来变换法线就可以得到正确的结果。
求变换法线的矩阵G又有几种不同的情景:
原变换矩阵只包含旋转变换,那么这个变换矩阵就是正交矩阵,根据定律:正交矩阵的逆矩阵就是它的转置矩阵。可以知道G就是原变换矩阵。所以可以直接使用原变换矩阵对法线进行变换。
变换只包含旋转和统一缩放,则只需要与缩放值k进行计算 : (1/k)Ma->b 来得出法线变换矩阵G。
变换中包含了非统一缩放,那就必须要老老实实求解逆矩阵来得出G。
Shader学习(9)法线和切线空间的定义和变换演示相关推荐
- UnityShader切线空间学习
此处连接凹凸感文章现在需要应用在立体的形状上 1.可视化切线空间 /// <summary> /// 可视化切线空间 /// </summary> public class T ...
- 切线空间、法线贴图、TBN矩阵
目录 1 法线贴图 1.1 为什么需要? 1.2 怎么做法线映射? 2 切线空间 2.1 为什么需要切线空间? 2.2 切线空间是什么? 2.3 TBN矩阵 2.4 TBN矩阵计算 3 光照计算是在` ...
- 处理顶点——通过切线空间的凹凸映射添加逐像素细节
问题 虽然前一个教程中具有不变法线的平面物体工作良好,但如果对一个曲面或有转角的表面进行凹凸映射仍会遇到麻烦. 主要问题是包含在凹凸映射中的偏离法线是在切线空间中的,这意味着它与默认法线有联系. 为了 ...
- Shader学习23——描边+辉光
研究了一下Post Processing,简单尝试了一下剑辉光效果 image.png 其实shader基本没啥变化,就是在描边的shader基础上加了点位置判断. 首先我们设置好Post Proce ...
- UE4 无需切线空间应用凹凸贴图
Unreal Engine 4.9 照亮环境 凹凸贴图(Bump mapping) 最早由一名图形程序员发明(1978 James Blinn),它通过调整后的着色计算 来创建凹凸表面的假象,无需增加 ...
- OpenGL核心技术之切线空间
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...
- Unity Shader - 切线空间的法线贴图应用(T2W W2T)
法线贴图 法线贴图(或是法线纹理)其实就是一张图片中的RGB通道分别存储着法线方向的纹理(有些为了数据压缩将X,Y存储在RG通道,Z是通过1-dot(xy,xy)来近似计算). 它的由来是因为高模运行 ...
- Unity Shader入门精要第四章:学习Shader 所需的数学基础--坐标空间
Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.4.6.1 为什么要使用这么多不同的坐标空间 二.4.6.3 顶点的坐标空间变换过程 4.6.4 模型空间 4.6.6 观察空间 4 ...
- OpenGL 法线贴图 切线空间 整理
1. What`s Bump Mapping? Bump Mapping通过改变几何体表面各点的法线,使本来是平的东西看起来有凹凸的效果,是一种欺骗眼睛的技术:). 我们知道,如果几何体表面有高低不平 ...
最新文章
- 国家五部委联合发布“AI标准顶层设计”:2021年明确、2023年初步建成
- 使用aotupep8自动批量调整代码以符合PEP-8规范
- android中bitmap压缩的几种方法的解读
- ConvLab介绍及使用
- 经典面试题(5):小心javascript自动插入分号机制
- 第六章 prototype和constructor
- 微信小程序SEO优化策略
- JAVA随机生成中文姓名,性别,Email,手机号,住址
- 职教mooc计算机组装与维护课程网课答案,2020-网课答案-高职心理辅导与教育-中国大学mooc...
- Hankson 的趣味题
- chromebook 笔记本 TrueNas 设置 wifi 连网
- html中的abbr有什么作用,html中关于abbr 标签的使用以及作用的详解
- AUTOCAD——快速提取边界线、CAD绘制单双开门
- sql语句查询时,where条件同时使用and和or
- 怎么桌面给计算机设密码,怎么设置电脑桌面密码
- 桌面图标有阴影,教给你怎么去掉
- java项目实体类方法找不到_报错,居然找不到实体类
- 全栈工程师的百宝箱:图形工具篇
- 北京联通KD-YUN-811E改桥接
- 数学建模-马尔萨斯人口问题