第三章 学习Shader所需的数学基础(4)
法线变换
法线(normal),也被称为法矢量(normal vector)。在以前我们已经讲过如何使用变换矩阵来变换一个顶点或方向矢量,但法线是需要我们特殊处理的一种方向矢量。在游戏中,模型的顶点往往会携带额外的信息,而顶点法线就是其中一种信息。当我们变换一个模型的时候,不仅需要变换它的顶点,还需要变换顶点法线,以便在后续处理(如片元着色器)中计算光照等。
一般来说,点和绝大部分方向矢量都可以使用同一个4×4或3×3的变换矩阵Ma->b把其从坐标空间A变换到坐标空间B中。但在变换法线的时候,如果使用同一个变换矩阵,可能就无法确保维持法线的垂直型。下面就来了解一下为什么会出现这样的问题。
我们先来了解另一种方向矢量——切线(tangent),也被称为切矢量(tangent vector)。与法线类似,切线往往也是模型顶点携带的一种信息。它通常与纹理空间对其,而且与法线方向垂直,如图所示。

由于切线是由两个顶点之间的差值计算得到的,因此我们可以直接使用用于变换顶点的变换矩阵来变换切线。假设,我们使用3×3变换矩阵Ma->b来变换顶点(注意,这里涉及到的变换矩阵都是3×3矩阵,不考虑平移变换,这因为切线和法线都是矢量,不会受平移影响),可以由下面的式子直接得到变换后的切线:

其中Ta和Tb分别表示在空间坐标A下和坐标空间B下的切线方向。但如果直接食用Ma->b来变换法线,得到的新的法线可能就不会与表面垂直了,下图给出了这样的一个例子:

那么,我们应该用哪个矩阵来变换法线呢?我们可以由数学约束条件来推出这个矩阵。我们知道一个顶点的切线Ta和法线Na必须满足垂直条件,即Ta·Na=0。给定变换矩阵Ma->b,我们已经知道Tb=Ma->bTa。我们现在想要找到一个矩阵G来变换法线Na,使得变换后的法线让然与切线垂直。即

对上式进行一些推导可得

由于

因此如果

那么上式即可成立。也就是说如果

即使用原变换矩阵的逆转置矩阵来变换法线就可以得到正确的结果。
值得注意的是,如果变换矩阵Ma->b是正交矩阵,那么

因此

也就是说我们可以使用用于变换顶点的变换矩阵来直接变换法线。如果变换只包括旋转变换,那么这个变换矩阵就是正交矩阵。而如果变换只包含旋转和统一缩放,而不包含非统一缩放,我们利用统一缩放系数k来得到变换矩阵Ma->b的逆转置矩阵

这样就可以避免计算逆矩阵的过程。而如果变换中包含了非统一的变换,那么我们就必须要求解逆矩阵来得到变换法线的矩阵。
第三章 学习Shader所需的数学基础(4)的更多相关文章
- 第三章 学习Shader所需的数学基础(2)
目录 1.坐标空间 1.2 坐标空间的变换 @ 1.坐标空间 我们在以前渲染流水线中就接触了坐标空间的变换.例如,在学习顶点着色器流水线阶段时,我们说过,顶点着色器的最基本功能就是把模型的顶点坐标从模 ...
- 第三章 学习Shader所需的数学基础(5)
1. Unity Shader的内置变量(数学篇) 使用Unity写shader的一个好处在于,它提供了很多内置参数,这使得我们不在需要自己手动算一些值.本文给出Unity内置的用于空间变换和摄像机以 ...
- 第三章 学习Shader所需的数学基础(3)
@[TOC] 1. 顶点的坐标空间变换过程 我们知道,在渲染流水线中,一个顶点要经过多个坐标空间的变换才能最终被画在屏幕上.一个顶点最开始是在模型空间中定义的,它最后会被变换到屏幕空间中,得到真正的屏 ...
- 第三章 学习Shader所需的数学基础(1)
1. 笛卡尔坐标系 在游戏中,我们使用的数学大部分都是为了计算位置.距离和角度等变量.而这些就算大部分是在笛卡尔坐标系下进行的. 1.1 二维笛卡尔坐标系 一个二维笛卡尔坐标系包含了两个部分的信息 1 ...
- Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础
摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐 ...
- 学习Shader所需的数学基础(坐标系,点和矢量)
数学对于计算机图形学的重要性是不言而喻的.在学习Shader之前,首先就要打好数学基础,好在入门Unity Shader所需的数学知识都是线性代数中很基础的的内容.按部就班的来,第一篇文章记录总结的是 ...
- 《ORACLE数据库管理与开发》第三章学习之常用函数记录
<ORACLE数据库管理与开发>第三章学习之常用函数记录 注:文章中的*代表所要操作的列名 1.lower(*)/upper(*),将此列下的值转为小写/大写 2.initcap(*):把 ...
- 《Linux内核设计与实现》第三章学习笔记
第三章 进程管理 姓名:王玮怡 学号:20135116 一.进程 1.进程的含义 进程是处于执行期的程序以及相关资源的总称,程序本身并不是进程,实际上就是正在执行的代码的实时结果.Linux内核通 ...
- 20135202闫佳歆--week6 课本第三章学习笔记
第三章 进程管理 一.进程 1.进程 进程就是处于执行期的程序. 进程就是正在执行的程序代码的实时结果. 进程是处于执行期的程序以及相关的资源的总称. 进程包括代码段和其他资源. 2.线程 执行线程, ...
随机推荐
- 入职第一天,装环境 .Ubuntu装jdk1.8,装idea 及tomcat
入职第一天,和之前公司的开发环境感觉天壤之别了,不过万变不离其宗,之前公司eclipse+widows.所以很少玩linux了.今天来就干了一件事.装环境 jdk安装. 下载地址:https://ww ...
- QA:无重复字符的最长子串
无重复字符的最长字串 leetcode地址:https://leetcode-cn.com/problems/longest-substring-without-repeating-character ...
- javascript 作用域链及性能优化
在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象.函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性.其中一个内部属 ...
- C表达式中的汇编指令
C 表达式中的汇编指令 asm 为 gcc 中的关键字,asm 表达式为在 C代码中嵌套汇编指令,该表达式只是单纯的替换出汇编代码,并不对汇编代码的含义进行解析. asm 表达式有两种形式,第二种 a ...
- python Django框架正式准备工作
之前由于不太了解数据库方面的知识,但经过一段时间的web应用的开发学习,成功的用其他框架连接了数据库,并完成了相关操作,数据爬取也初识了,更了解了python这门语言的语法,但路还很长,因此现在才能正 ...
- 小白学 Python(23):Excel 基础操作(上)
人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...
- 解决vue低版本安卓手机兼容性问题
低版本的安卓手机可能会白屏,是由新特性不支持引起的 解决代码es6新特性兼容问题 1,npm 安装 npm install babel-polyfill npm install es6-promise ...
- iOS核心动画高级技巧-2
3. 图层几何学 图层几何学 不熟悉几何学的人就不要来这里了 --柏拉图学院入口的签名 在第二章里面,我们介绍了图层背后的图片,和一些控制图层坐标和旋转的属性.在这一章中,我们将要看一看图层内部是如何 ...
- markdown总结 (webstrom快捷键)
# 在HbuilderX中写markdown(WebStrom快捷键配置)0. 一些快捷键和鼠标操作:1. ctrl+shift+↑ 当前行或者选中的块整体向上移动 ↓同理2. 向两侧扩大选择:A ...
- 缓冲&缓存&对象池概念的理解
一).缓冲 作用:缓解程序上下层之间的性能差异. 1).当上层组件的性能优于下层组件时加入缓冲机制可以减少上层组件对下 层组件的等待时间. 2).上层组件不需要等待下层组件接收全部数据,即可返回操作, ...