法线贴图、TBN矩阵
法线纹理
下图是一张法线纹理:
每个纹素的RGB值实际上表示的是XYZ向量:颜色的分量取值范围为0到1,而向量的分量取值范围是-1到1;可以建立从纹素到法线的简单映射
normal = (2*color)-1 // on each component
由于法线基本都是指向”曲面外侧”的(按照惯例,X轴朝右,Y轴朝上),因此法线纹理整体呈蓝色。
法线纹理的映射方式和漫反射纹理相似。麻烦之处在于如何将法线从各三角形局部空间(切线空间tangent space,亦称图像空间image space)变换到模型空间(着色计算所采用的空间)。
切线和副切线(Tangent and Bitangent)
大家对矩阵已经十分熟悉了,应该知道定义一个空间(本例是切线空间)需要三个向量。现在Up向量已经有了,即法线:可用Blender生成,或由一个简单的叉乘计算得到。下图中蓝色箭头代表法线(法线贴图整体颜色也恰好是蓝色)。
然后是切线T:垂直于法线的向量。但这样的切线有很多个:
这么多切线中该选哪个呢?理论上哪一个都行。但我们必须保持连续一致性,以免衔接处出现瑕疵。标准的做法是将切线方向和纹理空间对齐:
定义一组基需要三个向量,因此我们还得计算副切线B(本可以随便选一条切线,但选定垂直于另外两条轴的切线,计算会方便些)。
算法如下:记三角形的两条边为deltaPos1和deltaPos2,deltaUV1和deltaUV2是对应的UV坐标下的差值;则问题可用如下方程表示:
deltaPos1 = deltaUV1.x * T + deltaUV1.y * B
deltaPos2 = deltaUV2.x * T + deltaUV2.y * B
求解T和B就得到了切线和副切线!
已知T、B、N向量之后,即可得下面这个漂亮的矩阵,完成从切线空间到模型空间的变换:
有了TBN矩阵,我们就能把(从法线纹理中获取的)法线变换到模型空间。
可我们需要的却是从切线空间到模型空间的变换(个人觉得它这里说反了,有没有知道的大佬就解答),法线则保持不变。所有计算均在切线空间中进行,不会对其他计算产生影响。
只需对上述矩阵求逆即可得逆变换。这个矩阵(正交阵,即各向量相互正交的矩阵,参见下文”延伸阅读”小节)的逆矩阵恰好也就是其转置矩阵,计算十分简单:
invTBN = transpose(TBN)
亦即:
法线贴图、TBN矩阵相关推荐
- Learn OpenGL 笔记6.5 Normal Mapping(法线贴图)
我们通过在这些平面三角形上包裹 2D 纹理来增强真实感,隐藏多边形只是很小的平面三角形的事实. 从照明技术的角度来看,确定对象形状的唯一方法是通过其垂直法向量. 这种使用每片段法线与每表面法线相比的技 ...
- dx12 龙书第十九章学习笔记 -- 法线贴图
本章需要掌握的内容:①法线贴图②TBN坐标系 1.使用法线贴图的动机 左图是使用法线贴图后的结果,右图是没有使用法线贴图(使用法线插值)的结果.可以明显感知到,高光在右图中是分布在一条直线上的,并没有 ...
- OpenGL.Shader:9-学习光照-法线贴图(计算TBN矩阵)
OpenGL.Shader:9-学习光照-法线贴图(计算TBN矩阵) 这次文章学习法线贴图,法线贴图在游戏开发和GIS系统开发当中尤为广泛,其表现力特别的强,绘制的效果特别接近真实.更重要的一点就是, ...
- 切线空间、法线贴图、TBN矩阵
目录 1 法线贴图 1.1 为什么需要? 1.2 怎么做法线映射? 2 切线空间 2.1 为什么需要切线空间? 2.2 切线空间是什么? 2.3 TBN矩阵 2.4 TBN矩阵计算 3 光照计算是在` ...
- openGL法线贴图和纹理贴图结合使用,以增强三维物体表面细节
openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.法线贴图? 二.代码 1.主程序 2.着色器程序 运行效果 源码下载 前言 凹凸贴图的一种替代方法是使用查找表来替换法向量.这样 ...
- OpenGL3.3法线贴图
法线贴图 法线贴图:简单来说就是每一个片段都有他自己相应的法线的一个贴图 而不是一个平面统一使用同一个法线(这个贴图目前我知道的只能使用过ps制作出来 不会通过代码实现(很奇怪)) 法线贴图的使用方法 ...
- Unity Shader - 切线空间的法线贴图应用(T2W W2T)
法线贴图 法线贴图(或是法线纹理)其实就是一张图片中的RGB通道分别存储着法线方向的纹理(有些为了数据压缩将X,Y存储在RG通道,Z是通过1-dot(xy,xy)来近似计算). 它的由来是因为高模运行 ...
- opengl高级光照之法线贴图
法线贴图 opengl官方文档 核心修改的就是片段着色器中的normal值 uniform sampler2D normalMap; void main() { // 从法线贴图范围[0,1]获取法线 ...
- GAMES101学习-法线贴图学习笔记
参考:法线贴图_洛阳李四的博客 Bump.Normal和Displacement贴图的区别 闫神课上讲的关于法线贴图的定义和与位移贴图的区别已经很详细了,仅补充一些自己的理解和学习点. 法线贴图 No ...
最新文章
- ValueError: not enough values to unpack (expected 2, got 1)
- 用Asp.net 传送大文件
- MyBatis入门学习教程-调用存储过程
- WebBrowser
- Matlab scatter 如何显示不同颜色点状
- python中xrange函数_python中xrange和range的区别
- 利用钥匙串,在应用里保存用户密码的方法
- 假笨说-我是如何走上JVM这条贼船的
- 最大并发连接数和最大会话数的区别
- 最大流ISAP算法模板
- Android手机中怎么样在没root的情况下 修改 hosts 文件
- SpringSecurity案例之认证服务搭建
- 程序员浪漫起来到底有多可怕!
- IE8中伪元素动态作用样式不重绘bug记录
- RTTI decltype declval
- activityMq初步使用
- 计算机程序员crc算法,CRC-8校验原理及软件实现
- qq的云消息服务器,20 万台 QQ 服务器全面上云
- Android卡通农场闪退,卡通农场闪退解决办法
- 如何创建 2023 年营销日历(内含免费模板和示例)
热门文章
- 从LiveJournal后台发展看大规模网站性能优化方法 于敦德 2006-3-16
- 基于Java( Spring+SpringMVC+JDBC)+MySQL实现(Web)家电售后服务系统【100010064】
- docker compose 安装es和kibana
- 使用预训练语言模型预测阶段:GPU、CPU性能差别【Pegasus】
- 客制化键盘编程_【故事汇】客制化键盘讲解
- Learn to Grow: A Continual Structure Learning Framework for Overcoming Catastrophic Forgetting论文阅读
- 本题要求编写程序,从给定字符串中查找某指定的字符。
- 克鲁斯卡尔算法建立最小生成树
- Python统计学:如何理解单样本t检验?
- 编写 shell 脚本