详解OpenGL中的各种变换(投影变换,模型变换,视图变换)(完)——法线变换
前面两节内容已经说完了所有的三种变换。也就是说我们现在程序里面既不需要glLookAt(),也不需要gluPerspective(),这些矩阵我们都可以自己写。然后,再用glMultMatrix()来调用这些矩阵,注意一点就是OpenGL是左乘,前面给出的矩阵都是右乘矩阵,所以调用的时候需要转置,摆放的位置也要注意。当然,如果用shader的话,这些函数也就用不到了,矩阵顺序也可以自己定义。这里所有的变换都是作用在顶点(Vertex)上的,但是还有一类数据需要进行变换,那就是顶点法线。我们在计算光照的时候,需要在顶点上设置顶点发现,顶点经过各种变换,法线肯定也要跟着变。不过法线的变化跟顶点有些许的不同,本文就介绍下法线变换。
首先,我们需要知道法线的几个注意的地方:
- 法线向量是需要进行归一化的,它的长度必须为1.0。
- 法线向量是表示方向的,跟顶点不一样不是表示位置,所以法线向量只有三个分量,不存在齐次坐标。
- 法线向量的变换中,一般只有旋转变换和部分缩放变换。因为法线向量表示方向,平移后不变化,而且法线如果等轴缩放,归一化后也不变化,另外,法线主要是计算光照,透视变换也用不到。
跟直觉违背的是,法线向量的变换与顶点向量的变换方式是不同的。那么如何变换法线呢?我们首先取出变换矩阵的左上角的3*3矩阵。因为法线向量只需要包含必要的旋转和缩放信息,也可以将物体从模型坐标系变换到眼(相机)坐标系。公式如下:

图1
我们现在现在看看为何需要求逆后转置。如图2所示,我们如果直接将法线向量乘以M,就会出现中间的这种情况,其法线分布明显与表面不垂直,而最右边的图才是正确变换后的法向分布。

图2
我们接下来证明一下公式。这里假设某一点处的法向量为n,切向量为t,由两者在曲面上的垂直关系可知:

图3
假设顶点开始变换,最终的变换矩阵为M,那么变换后的切向量为t'=Mt。切向量可以通过几何分析来验证变换矩阵和顶点是一致的,这里就不详述了。那么我们可以得到变换后的n'和t'之间的关系:

图4
我们根据上式可以得到中间两项GTM=I,所以我们得到最终的发现变换矩阵:

图5
这里就介绍完所有的变换矩阵了,真是一个漫长的过程。其实在这些变换后还有一个视口变换,就是将光栅化后的图像映射到窗口中,但由于这一步时管线内部的操作,这次也就没提了。大家可以试着自己写一下各种矩阵,肯定对OpenGL视图和变换这块更加理解。
详解OpenGL中的各种变换(投影变换,模型变换,视图变换)(完)——法线变换的更多相关文章
- jQuery:详解jQuery中的事件(二)
上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...
- 图文详解Unity3D中Material的Tiling和Offset是怎么回事
图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...
- 【转】详解C#中的反射
原帖链接点这里:详解C#中的反射 反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...
- 详解Webwork中Action 调用的方法
详解Webwork中Action 调用的方法 从三方面介绍webwork action调用相关知识: 1.Webwork 获取和包装 web 参数 2.这部分框架类关系 3.DefaultAction ...
- 【转】详解JavaScript中的this
ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...
- 深入详解SQL中的Null
深入详解SQL中的Null NULL 在计算机和编程世界中表示的是未知,不确定.虽然中文翻译为 “空”, 但此空(null)非彼空(empty). Null表示的是一种未知状态,未来状态,比如小明兜里 ...
- java 乱码详解_jsp中pageEncoding、charset=UTF -8"、request.setCharacterEncoding("UTF-8")
http://blog.csdn.net/qinysong/article/details/1179480 java 乱码详解__jsp中pageEncoding.charset=UTF -8&quo ...
- 详解Objective-C中委托和协议
Objective-C委托和协议本没有任何关系,协议如前所述,就是起到C++中纯虚类的作用,对于“委托”则和协议没有关系,只是我们经常利用协议还实现委托的机制,其实不用协议也完全可以实现委托. AD: ...
- 举例详解Python中的split()函数的使用方法
这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:sp ...
随机推荐
- checking在浏览器为应用缓存查找更新时触发
离线的Web应用,就是在设备不能上网的时候还能运行应用.html5把离线应用作为重点,主要是开发人员的心愿.离线应用的开发的步骤有:首先应该知道设备是否能够上网;然后应该还能访问一定的资源(如图像.C ...
- 内存调试工具Electric Fence
源码下载地址 注:官方地址下载不了,可能不再维护了,此是一个老项目 efence中相关环境变量控制: 302 /* 303 * See if the user wants to allow mallo ...
- NV Perf Kit
https://developer.nvidia.com/gameworksdownload#?dn=perfkit-4-0-0 Title Version Release Date PerfKit ...
- 优雅的函数式编程--Clojure概述
欢迎转载,转载请注明出处,徽沪一郎. 楔子 由于阅读storm源码的原因,头一次接触到Clojure.没有花特别的时间来研究clojure语法,只是在一些特殊的用法时,才查了一下clojure官网的文 ...
- DS实验题 Dijkstra算法
参考:Dijkstra算法 数据结构来到了图论这一章节,网络中的路由算法基本都和图论相关.于是在拿到DS的实验题的时候,决定看下久负盛名的Dijkstra算法. Dijkstra的经典应用是开放最短路 ...
- WITCH CHAPTER 0 [cry] 绝密开发中的史克威尔艾尼克斯的DX12技术演示全貌
西川善司的[WITCH CHAPTER 0 cry]讲座 ~绝密开发中的史克威尔艾尼克斯的DX12技术演示全貌 注:日文原文地址: http://pc.watch.impress.co.jp/d ...
- PHP笔记——java程序员看懂PHP程序
PHP笔记——java程序员看懂PHP程序 php是一种服务器端脚本语言,类型松散的语言. <?php ?> xml风格 <script language=”ph ...
- 20145235《Java程序设计》第7周学习总结
教材学习内容总结 13.1 认识时间与日期 格林威治时间(GMT):通过观察太阳而得,因为地球公转轨道为椭圆形且速度不一,本身自传减速而造成误差. 世界时(UT):通过观测远方星体跨过子午线而得,受地 ...
- Jsp入门学习笔记
#Jsp入门 一.JSP基础语法 1.JSP指令: page inlcude taglib 2.JSP注释: a.html注释: <!-- abcdefghijklmn --> b.jsp ...
- Java多态与C++中多态的实现
大牛的文章,值得拜读http://www.ibm.com/developerworks/cn/java/j-lo-polymorph/ 粘贴过来好多图片丢失了 /(ㄒoㄒ)/~~ 众所周知,多态是面向 ...