前面两节内容已经说完了所有的三种变换。也就是说我们现在程序里面既不需要glLookAt(),也不需要gluPerspective(),这些矩阵我们都可以自己写。然后,再用glMultMatrix()来调用这些矩阵,注意一点就是OpenGL是左乘,前面给出的矩阵都是右乘矩阵,所以调用的时候需要转置,摆放的位置也要注意。当然,如果用shader的话,这些函数也就用不到了,矩阵顺序也可以自己定义。这里所有的变换都是作用在顶点(Vertex)上的,但是还有一类数据需要进行变换,那就是顶点法线。我们在计算光照的时候,需要在顶点上设置顶点发现,顶点经过各种变换,法线肯定也要跟着变。不过法线的变化跟顶点有些许的不同,本文就介绍下法线变换。

  首先,我们需要知道法线的几个注意的地方:

  1. 法线向量是需要进行归一化的,它的长度必须为1.0。
  2. 法线向量是表示方向的,跟顶点不一样不是表示位置,所以法线向量只有三个分量,不存在齐次坐标。
  3. 法线向量的变换中,一般只有旋转变换和部分缩放变换。因为法线向量表示方向,平移后不变化,而且法线如果等轴缩放,归一化后也不变化,另外,法线主要是计算光照,透视变换也用不到。

  跟直觉违背的是,法线向量的变换与顶点向量的变换方式是不同的。那么如何变换法线呢?我们首先取出变换矩阵的左上角的3*3矩阵。因为法线向量只需要包含必要的旋转和缩放信息,也可以将物体从模型坐标系变换到眼(相机)坐标系。公式如下:

图1

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

图2

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

图3

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

图4

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

图5

  这里就介绍完所有的变换矩阵了,真是一个漫长的过程。其实在这些变换后还有一个视口变换,就是将光栅化后的图像映射到窗口中,但由于这一步时管线内部的操作,这次也就没提了。大家可以试着自己写一下各种矩阵,肯定对OpenGL视图和变换这块更加理解。

详解OpenGL中的各种变换(投影变换,模型变换,视图变换)(完)——法线变换的更多相关文章

  1. jQuery:详解jQuery中的事件(二)

    上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...

  2. 图文详解Unity3D中Material的Tiling和Offset是怎么回事

    图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...

  3. 【转】详解C#中的反射

    原帖链接点这里:详解C#中的反射   反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...

  4. 详解Webwork中Action 调用的方法

    详解Webwork中Action 调用的方法 从三方面介绍webwork action调用相关知识: 1.Webwork 获取和包装 web 参数 2.这部分框架类关系 3.DefaultAction ...

  5. 【转】详解JavaScript中的this

    ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...

  6. 深入详解SQL中的Null

    深入详解SQL中的Null NULL 在计算机和编程世界中表示的是未知,不确定.虽然中文翻译为 “空”, 但此空(null)非彼空(empty). Null表示的是一种未知状态,未来状态,比如小明兜里 ...

  7. 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 ...

  8. 详解Objective-C中委托和协议

    Objective-C委托和协议本没有任何关系,协议如前所述,就是起到C++中纯虚类的作用,对于“委托”则和协议没有关系,只是我们经常利用协议还实现委托的机制,其实不用协议也完全可以实现委托. AD: ...

  9. 举例详解Python中的split()函数的使用方法

    这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下   函数:sp ...

随机推荐

  1. 李洪强 - C语言8-Scanf函数

    C语言的scanf函数 一.变量的内存分析 (一)字节与地址 ①. 内存以字节为单位 每个字节都有自己的内存地址,根据地址就可以找到该字节.整个内存相当于一整个酒店,而酒店以房间为单位,在这里每个房间 ...

  2. java执行时的两个常见问题(无法加载主类)

    问题1:javac不是内部或者外部命令 问题2:找不到或无法加载主类*** 这两个问题都和jdk的配置有关,一个是path一个是classpath.path:去哪里找编译或运行等工具(必须设置),cl ...

  3. CSV to XLSX (专用)

    $csvFile = "F:\ACL\HZ ACL\ACL-APAC.CSV" $path = "F:\ACL\HZ ACL\ACL-APAC.XLSX" $r ...

  4. Spring3.1 Cache注解

    依赖jar包: <!-- redis --> <dependency> <groupId>org.springframework.data</groupId& ...

  5. $.each(),$.map()归纳

    //$.each()对字典(没有索引).数组(有索引) 遍历 //两个参数 var json={"name":"李可","age":&quo ...

  6. 前端CSS参考阅读

    CSS 2.2 W3标准 http://dev.w3.org/csswg/css2/ CSS2 中文翻译 http://files.cnblogs.com/files/mize/CSS2_Chines ...

  7. mongodb 3.2 分片部署步骤

    #linux 网络优化1. 文件中/etc/sysctl.conf, 加入net.core.somaxconn = 2048fs.file-max = 2000000fs.nr_open = 2000 ...

  8. MySQL 命令行导出、导入Select 查询结果

    <!-- 环境: Windows 2003 SP2 + MySQL5.5.28 Author: 博客园小dee --> 有的时候需要把在一张表中用 select 语句查询出来的结果保存到另 ...

  9. CentOS安装TortoiseSVN svn 客户端

    CentOS安装TortoiseSVN svn 客户端   一.CentOS安装TortoiseSVN yum install -y subversion 二.SVN客户端命令 1.查看帮助 命令:s ...

  10. Bootstrap页面布局6 - BS把已有的固定宽度布局转换成响应式布局

    首先引入文件bootstrap-responsive.css <link href="bootstrap/css/bootstrap-responsive.css" rel= ...