切线空间(TangentSpace)的计算与应用

切线空间(TangentSpace)的计算与应⽤
转:自动扶梯装饰
概要
本篇⽂章主要讲解计算机图形学中切线空间是如何计算的,且会以法线贴图的例⼦来验证切线空间是否计算正确,以及展现切线空间的⽤途.本⽂需要读者掌握⼀定的 3D 坐标空间变换和简单光照相关的知识,以及法线贴图的基本知识(但切线空间不仅仅只⽤于法线贴图)。
认识切线空间
什么是切线空间
切线空间 (Tangent Space) 与 世界空间 (World Space) 和 观察空间 (View Space) ⼀样,都是⼀个坐标空间,它是由顶点所构成的平⾯的 UV 坐标轴以及表⾯的法线所构成,⼀般⽤ T (Tangent), B (Bitangent), N (Normal) 三个字母表⽰,即切线,副切线,法线, TT 对应UV 中的 UU, BB 对应 UV 中的 VV,下图是切线空间的⽰意图:
微晶钢
这⾥可能会有⼀个疑问,就是为什么 TT 对应 UV 中的 UU, BB 对应 UV 中的 VV 。理论上,只要 TT 和 BB 垂直且都位于三⾓形的平⾯内,就可以达到使⽤切线空间的⽬的,因为这样我们总可以把所有需要的数据变换到同⼀个坐标空间下,但由于我们知道 UV 坐标的值,所以⽤ UV 坐标来对应 TT 和 BB 计算出数据了。
为什么要有切线空间
要理解为什么要有切线空间,可以从法线贴图⼊⼿。众所周知,绝⼤部分的法线贴图,颜⾊都是偏蓝⾊的,这是因为法线贴图中存储的法线向量⼤部分都是朝向或者接近 z 轴的,即 (0,0,1)(0,0,1),换算到 RGB 中,就是偏向蓝⾊,即 (0.5,0,5,1)(0.5,0,5,1) (后⾯的 Shader
中有算法),这种贴图就是切线空间 (Tangent Space)下的贴图。这显然存在⼀个问题,想象⼀个位于世界坐标原点且没有进⾏任何变换的⽴⽅体,表⾯法线⽅向就有 6 个,因为有 6 个不同朝向的⾯(确切的说,可能是 12 个⾯,因为⼀个矩形⼀般由两个三⾓形组成),⽽且每个⾯完全相同,所以这时候我应该只需要⼀个⾯的法线贴图就可以了。但其实这时再⽤这种偏蓝⾊的法线贴图就不⾏了,因为⽴⽅体的上表⾯在世界空间的法线⽅向为 (0,1,0)(0,1,0),⽽在法线贴图中采样出来的法线基本都是接近于 (0,0,1)(0,0,1) 的,使⽤错误的法线会得到错误的光照结果。所以这时候需要做⼀张包含⽴⽅体所有⾯的法线信息的法线贴图,也就是模型空间 (Object Space)下的法线贴图,⽽这种贴图看起来就不单单是偏蓝⾊了,⽽是包含了多种颜⾊。
这样看起来好像也没什么问题,但其实⽤切线空间下的法线贴图要⽐⽤模型空间下的法线贴图要有⼀些优势:
可以复⽤:⽐如上⽂提到的⽴⽅体,如果每个⾯都完全相同,则可以只制作⼀个⾯的法线贴图,然后
就可以复⽤到所有⾯上,类似的复⽤需求还有很多,这可以减⼩内存占⽤和包体⼤⼩。
纹理可以压缩:因为切线空间下,⼀般来说法线⽅向不会是朝向表⾯内部,即法线贴图中的 z 值不会是负数,⽽我们使⽤的法线⼜是归⼀化的,所以完全可以根据 x 和 y 的值来推导出 z 的值,所以贴图中只需要存储 x 和 y 的值即可,可进⾏纹理压缩。
待补充
综上所述,⼀般的法线贴图都是使⽤切线空间的,⽽直接使⽤切线空间下的法线贴图⼜会出现之前提到的⽴⽅体的那个问题,所以我们在使⽤前需要先进⾏切线空间相关的变换,把所需要的数据变换到同⼀个坐标空间下再进⾏计算(可以全部变换到世界空间也可以全部变换到切线空间)。
新型增塑剂切线空间的计算
求切线和副切线
要进⾏切线空间相关的计算,需要先求出构成切线空间三个轴的单位基向量,然后就可以构造出从切线空间变换到世界空间的矩阵,从⽽进⾏之后的计算。
切线空间的计算可以通过前⾯的⽰意图来理解,这⾥为了⽅便,再放⼀次:
设:
元器件清单则由图和共⾯向量基本定理可知:
包塑轴承
观察这两个等式,我们发现这其实可以写成矩阵乘法的形式,如下所⽰:
如果你求解⼀下等号右边的矩阵乘法,你就会发现,他就是我们在上⾯得到的等式。根据这个矩阵形式的等式,我们不难求解 TB 矩阵,只需要两边同时左乘 ΔUΔV 的逆矩阵,再进⾏计算即可,步骤如下:
草地悠波球
逆矩阵的计算公式为 矩阵的⾏列式的值的倒数再乘以它的伴随矩阵 (Adjugate Matrix, 如果对这些概念不熟悉需要读者⾃⾏查阅),其实伴随矩阵的求解并不容易,不过 ⼆阶矩阵的伴随矩阵 有⼀个简单的公式,即 主对⾓线的元素互换,副对⾓线的元素乘以 −1 ,所以最终结果如下所⽰:
似乎我们还缺少 E1和 E2 的信息,但其实这个信息是已知的,因为他们就是三⾓形的两个边,⽽三⾓形的顶点坐标是我们知道的,所以求出 T 和 B 所需的数据我们都已经有了,只需要代⼊公式就可以了。
设:
则:
B 也可以如此求解,但其实只需要⽤ T 和 法线向量 叉乘 即可。
归⼀化
因为 E1 和 E2是⽤顶点坐标表⽰的,⽽ U 和 V 是纹理坐标,他们的坐标单位是不同的,所以我们求出的结果⾃然不太可能是已经归⼀化了的,⽽我们使⽤坐标空间转换矩阵的时候需要的是归⼀化的坐标,所以我们需要进⾏归⼀化。
法线贴图的例⼦
本节将以⼀个法线贴图的例⼦,来展⽰切线空间是如何⼯作的,在这个例⼦中,我只计算了漫反射等颜⾊(因为除了法线贴图外我只到⼀张漫反射的贴图,但⾜够演⽰⽤了,不过光照效果看起来未必会很好),下⾯两张图是我使⽤的漫反射贴图和法线贴图:
计算顶点数据
为了⽅便展⽰,我准备了⼀个⽴⽅体的顶点数据,⼀共有36个顶点(6个⾯,每个⾯2个三⾓形),为了这篇⽂章的编写⽅便,我采⽤直接绘制顶点⽽⾮索引的⽅式,并且之后的⼀些计算会有些暴⼒。
36个顶点数据如下所⽰,每⼀⾏分别为顶点坐标(3个),法线向量(3个),以及纹理坐标(2个),每6⾏为⼀个⾯。
float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,

本文发布于:2024-09-22 00:57:50,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/167898.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:空间   切线   法线   贴图
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议