在WebGL开始绘制之前,我们需要通过自己对3D空间进行矩阵和向量的运算,使用网上已经成熟的转换库,可以避免自己去实现这些复杂的数学运算。
我们这里选择的是gl-matrix库,下载地址:https://github.com/toji/gl-matrix

变换运算

在最终开始绘制之前,我们需要把3D世界中的物体的坐标系转换为WebGL的坐标系,确定最终绘制的位置。

模型变换(顶点着色器阶段处理)

模型变换用来确定一个模型在世界坐标系中的位置,所有的模型都有一个世界坐标系的矩阵,保证所有模型都处于同一个坐标系(即世界坐标系)之中,模型变换包括平移,旋转和缩放;

视图变换(顶点着色器阶段处理)

有了世界坐标系之后还不够,还需要一个同样位于该坐标系之中的摄像机的矩阵,用来表示观察者观看的位置和角度;

模型视图变换(顶点着色器阶段处理)

该变换就是模型变换和视图变换相乘之后的变换矩阵;

投影变换(顶点着色器阶段处理)

我们在这一步得到了物体在摄像机中看起来的最终坐标,但是和我们人眼可以看见的景象还是有所区别,比如我们看世界上的东西都是由一种近大远小的透视效果,投影变换就是用来实现这些效果的变换;

正交投影

正交投影,可以看做是一种平行投影,正交投影下的物体没有近大远小的视觉效果,无论远近看起来都是一样大的,该投影一般用在2D或2.5D(一般是3D角色2D场景)游戏中,3D游戏的UI实现也会用到该投影;

使用gl-matrix库创建正交投影代码如下:

 var m4 = glMatrix.mat4.create();
// 通过设定每个面的大小确定投影区域
glMatrix.mat4.ortho(m4, -100, 100, -100, 100, -100, 100);

透视投影

透视投影,可以模拟人眼所看见的3D世界的近大远小的视觉效果,该投影一般用在3D游戏中;

使用gl-matrix库创建透视投影代码如下:

 var m4 = glMatrix.mat4.create();
// 方法1:通过垂直范围、高宽比和近远面确定投影区域
glMatrix.mat4.perspective(m4, 1, 1, 0, 100);
// 方法2:通过设定每个面的大小确定投影区域
glMatrix.mat4.frustum(m4, -100, 100, -100, 100, -100, 100);

透视除法(图元装配阶段处理)

透视除法即使用w分量除以x,y,z分量(w默认值是1),产生三维的透视效果。

更多的信息可以参考:https://www.jianshu.com/p/7e701d7bfd79

视口变换(图元装配阶段处理)

视口变换主是将三维空间中的物体投影到二维的平面上,在计算机图形学中,它的定义是将经过几何变换,投影变换和裁剪变换后的物体显示于屏幕指定区域内。

用户可以通过调用两个方法来控制这个步骤的变换:

gl.viewPort

确定最终显示的位置和尺寸,单位为像素;

gl.depthRange

确定最终可以显示出来的深度区域,可选范围[0-1];

完整的变换管线(变换流水线)如下图所示

变换顺序的重要性

3D应用中矩阵的乘法非常重要,我们需要注意的是,矩阵的两个乘数交换之后,得到的结果是不一样的。
MN≠NM
可以看下面的图直观的了解下不同的变换顺序得到不同的结果:

变换矩阵堆栈

一般说来,矩阵堆栈常用于构造具有继承性的模型,即由一些简单目标构成的复杂模型。例如,一辆自行车就是由两个轮子、一个三角架及其它一些零部件构成的。它的继承性表现在当自行车往前走时,首先是前轮旋转,接着是后轮旋转,然后整个车身向前平移,如此进行下去,这样自行车就往前走了。
另外当我们需要实现复杂模型绘制时,会需要全局坐标和本地坐标的概念,比如,一个桌子放在全局坐标的某个位置上,这个桌子内部包含了一个桌面和四个腿,这5个模型的矩阵的数据是相对桌子的本地坐标,而不是记录全局坐标,我们希望,在桌子的矩阵改变时,内部的5个模型的本地矩阵不需要改变。

入栈

当前矩阵乘于栈顶矩阵之后的值,作为新的栈顶矩阵压入栈中,可以理解为当前栈顶矩阵就是的本地坐标使用的矩阵;

出栈

弹出栈顶的矩阵,当前的栈顶矩阵就是上一个本地坐标的父级坐标矩阵;
通过变换矩阵堆栈绘制桌子:
  1. 压入桌子的矩阵;
  2. 用栈顶矩阵乘于桌面的矩阵,得到桌面位于全局坐标的矩阵;
  3. 压入桌面的矩阵,当桌面上需要绘制物体时,可以使用该栈顶矩阵乘于需要绘制的物体的矩阵;
  4. 桌面已经没有物体需要绘制了,弹出栈顶的矩阵(即桌面的矩阵);
  5. 此时栈顶的矩阵即桌子的矩阵,用栈顶的矩阵乘于第一个腿的矩阵,得到第一个腿的全局坐标的矩阵;
如此往复,直到绘制完所有的模型;

示例

WebGL学习笔记(五):变换库的更多相关文章

  1. webgl学习笔记五-纹理

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...

  2. WebGL学习笔记五

    本章主要是对纹理的进一步讲解,我们很多时候需要将现实中已有 的图片在网页中展示出来而不是去创造图片,通过纹理 我们可以将光栅化的图形和图片纹理形成映射并且将图片在图形 中显示出来.基本过程与前几章一致 ...

  3. CMake学习笔记五-依赖库添加

    # # 项目名称 # SET(WIS_PROJECT_NAME EXAMPLE) # dependencies SET(DEPENDENCIES #依赖第三方库 ) #Qt模块 SET(QT_MODU ...

  4. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

  5. openresty 学习笔记五:访问RabbitMQ消息队列

    openresty 学习笔记五:访问RabbitMQ消息队列 之前通过比较选择,决定采用RabbitMQ这种消息队列来做中间件,目的舒缓是为了让整个架构的瓶颈环节.这里是做具体实施,用lua访问Rab ...

  6. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  7. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  8. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  9. Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  10. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

随机推荐

  1. 《大象 Thinking in UML》读书笔记:软件开发——从现实世界到对象世界

    参考:Process-oriented vs. Object-oriented 前言 软件行业在采用OO的思想后,从一开始只对编码使用OO,到现在“分析-设计-编码”全部环节使用OO,形成了OOA.O ...

  2. X509IncludeOption 枚举

    X509IncludeOption 枚举 指定 X.509 数据应包括 X.509 证书链的哪些内容. EndCertOnly 2 X.509 链信息中仅包括最终证书. ExcludeRoot 1 包 ...

  3. 下载恶意pcap包的网站

    说几个我经常用的,免费的:1.  Malware  Traffic  Analysis:  http://www.malware-traffic-analysis.net/2018/index.htm ...

  4. Error while obtaining UI hierarchy XML file: com.android.ddmlib.SyncException: Remote object doesn't

    在使用真机定位页面元素时启动uiautomatorviewer.bat ,报错Error while obtaining UI hierarchy XML file: com.android.ddml ...

  5. mybatis框架-查询用户表中的记录数

    之前已经搭建过mybatis框架了,现在我们要用mybatis框架真正的干点事情了. 这是这个简单web项目的整体架构. 我们使用mybatis框架查询用户表中的记录数: 这是用户类: package ...

  6. 学习Spring-Data-Jpa(十七)---对Web模块的支持

    Spring-Data还提供了Web模块的支持,这要求Web组件Spring-MVC的jar包位于classpath下.通常通过使用@EnableSpringDataWebSupport注解来启用继承 ...

  7. Windows10 Faster R-CNN(GPU版) 运行 Demo

    上篇文章介绍了 TensorFlow 环境的搭建,这篇介绍 demo 运行 参考链接 参考链接2 1. 下载 TensorFlow object detection API 相关文件 点击跳转下载文件 ...

  8. SQL基础-创建新的输出字段

    一.创建新的输出字段 1.建表.插数据 ### CREATE TABLE `t_stock_trans_dtl` ( `trans_id` varchar(100) NOT NULL COMMENT ...

  9. GoCN每日新闻(2019-10-11)

    GoCN每日新闻(2019-10-11) GoCN每日新闻(2019-10-11) 1. golang 将数据库转换为gorm结构 https://studygolang.com/articles/2 ...

  10. Linux 服务器快速搭建 Java Web 开发环境

    搭建 Java 环境 yum list java* yum install java-1.8.0-openjdk.x86_64 -y java -version mkdir 创建文件夹 mv 修改文件 ...