OpenGL ES 矩阵变换及其数学原理详解(五)
引子
- 向量刻画的是线性空间中的对象。
- 矩阵刻画的是向量在线性空间中的运动(变换,跃迁),相似矩阵本质上就是同一个线性变换的不同的描述。
- 在一个线性空间中,选定了一组基,对于任何一个线性变化都可以用一个确定的矩阵来描述
- 矩阵不仅可以作为线性变换的描述,而且可以作为一组基的描述,作为变换的矩阵,不但可以把线性空间中的一个点给变换到另一个点去,而且也能够把线性空间中的一个坐标系(基)表换到另一个坐标系(基)去。
- 当我们谈到向量时,一定要指定它所在的坐标系才有意义,比如向量b=(1,2,3)实际上指的是在单位坐标系I下有一个向量的度量为b。
- 就可以理解Ma=b就可以看成Ma=Ib,就是说在坐标系M中度量出来的向量a和在坐标系I里面度量出来的b实际上就是同一个向量。
- 对于矩阵而言,他表示出来的那个坐标系也是由一组基(向量)组成的,同样存在这组基实在哪个坐标系下度量的问题。对于矩阵M,将其理解成IM,即M中的那组向量是在I坐标系中得出的。
- MxN本质是声明了一个在M坐标系中量出的另一个坐标系N,其中M本身是在I坐标系中度量出来的。
- 对坐标系施加变换的方法,就是让表示那个坐标系的矩阵与表示那个变化的矩阵相乘。
因此我们来理解这样一个式子,ACb,AC为矩阵,b为一个向量
- b是一个向量,他是在I坐标系下度量的,a = Cb也就是在I坐标系下将向量b变换到向量b,d=ACb=Aa的含义就是继续在I坐标系下将向量a变换到向量d。即在同一个坐标系I下面进行了两次变换操作。
- 另一种理解方式是ACb=IACb,那么IAC三个矩阵相乘就表示了坐标系的变换,在I坐标系中度量处新的坐标系IA,再在IA坐标系下度量出IAC,然后这里最终的坐标系中的向量b和在1中在I坐标系中经过两次变换得到的向量是同一个向量。
上面的两种理解方式也揭示了对向量的变换和对坐标系的变换是等价的,这一点也可以通过后面旋转变换的图示中看出来。
各种变换
平移矩阵
缩放矩阵
平移矩阵和缩放矩阵很容易理解,并且从矩阵形式我们也可以看到为什么用四维的向量表示一个顶点了,除了w分量用来做透视除法以外,另一个作用不也正好是为了把平移整合进来吗,都做乘法而不做加法。在数学上也就是将三维空间的坐标表示成其齐次形式.
旋转变换
旋转变换相对来说较为复杂,对绕x、y或z轴旋转的情况比较好理解。
以绕z轴旋转为例
于是
写成矩阵形式为
绕任意轴旋转的旋转矩阵为
同理,前面学到的正交投影矩阵,透视矩阵以及摄像机矩阵,本质上和上面的变换都是一样的。
前面可以看到一般传入渲染管线的是一个由摄像机矩阵,投影矩阵,变换矩阵相乘得到的总的变换矩阵,
在顶点着色器中一般是这样的形式
gl_Position = uMVPMatrix * vec4(aPosition,1);
上面的代码中的变量uMVPMatrix表示了模型(M)、视图(V)、投影(P)三中变换综合,
注意到矩阵乘法的顺序,对每个点所做的变换是有顺序的,对每个点先进行模型变换(平移缩放旋转)、再进行视图变换(摄像机视角)再进行投影变换,这三个变换顺序是不可变得,因为改变顺序最终看到的效果都是不一样的。
对每个点所做的综合变换本质上就是对这个点进行矩阵相乘,然而就我们传入的是最终的综合变换矩阵而言,刚才的理解不是特别准确,换个思路理解成综合变换矩阵就是对坐标系的变换会更好,因为毕竟我们是一次性将这个相乘后的综合矩阵传进去的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
相关推荐
-
OpenGL ES着色器使用详解(二)
本文介绍了OpenGL ES着色器使用的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.着色器语言 着色器语言是一种高级图形编程语言,和C/C++语言很类似,但存在很大差别,比如,不支持double,byte ,short,不支持unin,enum,unsigned以及位运算等,但其加入了很多原生的数据类型,如向量,矩阵等. 数据类型可分为标量.向量.矩阵.采样器.结构体.数组等 向量 向量传递参数,如果只提供一个标量,这个值用于设置所有向量的值:如果输入是多个标量或者是矢量,从左到
-
OpenGL ES实现光照效果(六)
为了演示光照效果,在前面学习过的内容基础上我们首先创建一个立方体,同时为了看起来直观一些,这个立方体每个面采用中心为白色,周围红色的渐变方案,不然看上去同样的颜色混在一起,看不出来是否是立方体.并且添加上转动旋转功能,这样转动起来立体感更强一些. 一个立方体 立方体类Rectangle.java public class Rectangle { private FloatBuffer mVertexBuffer; private int mProgram; private int mPositi
-
java实现OpenGL ES纹理映射的方法
本文实例讲述了java实现OpenGL ES纹理映射的方法.分享给大家供大家参考.具体如下: 1. GlRenderer.java文件: package net.obviam.opengl; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GL
-
OpenGL ES透视投影实现方法(四)
在之前的学习中,我们知道了一个顶点要想显示到屏幕上,它的x.y.z分量都要在[-1,1]之间,我们回顾一下渲染管线的图元装配阶段,它实际上做了以下几件事:剪裁坐标.透视分割.视口变换.图元装配的输入是顶点着色器的输出,抓哟是物体坐标gl_Position,之后到光栅化阶段. 图元装配 剪裁坐标 当顶点着色器写入一个值到gl_Position时,这个点要求必须在剪裁空间中,即它的x.y.z坐标必须在[-w,w]之间,任何这个范围之外的点都是不可见的. 这里需要注意以下,对于attribute类型的
-
OpenGL ES正交投影实现方法(三)
本文实例为大家分享了OpenGL ES正交投影展示的具体代码,供大家参考,具体内容如下 绘制正方形 在最开始绘制的六边形里面好像看起来挺容易的,也没有出现什么问题,接下来不妨忘记前面绘制六边形的代码,让我们按照自己的理解来绘制一个简单的正方形. 按照我的理解,要想在屏幕中间显示一个正方形,效果如下图所示 应该创建的数据如下图所示 即传给渲染管线的顶点数据如下图: float[] vertexArray = new float[] { (float) -0.5, (float) -0.5, 0,
-
OpenGL ES纹理详解
使用前面学过的技术已经可以利用OpenGL ES构建立体图形,并通过顶点着色器和片元着色器对其进行各种变化呢和光照等效果使得三维效果更加真实,实际上我看看到很多的3D游戏漂亮多了,那是因为有各种各样的漂亮的图像带给人很多视觉盛宴,这篇文章在前面的基础上,增加物体的表面贴图,使得物体更加好看. 纹理概念 纹理用来表示图像照片或者说一系列的数据,使用纹理可以使物体用用更多的细节.OpenGL ES 2.0 中有两种贴图:二维纹理和立方体纹理. 每个二维纹理都由许多小的纹理元素组成,类似与片元和像素,
-
OpenGL ES渲染管线概述(一)
渲染管线一般是由显示芯片GPU内部处理图形信号的并行处理单元组成,这些并行处理单元之间是独立的,从另一个角度看,渲染管线实际上也是一系列绘制过程,这一系列过程的输入是待绘制物体的相关描述信息,输出的是要显示的图像帧数据. OpenGL ES管线主要包括: 读取顶点数据->顶点着色器->组装图元->光栅化图元->片元着色器->写入帧缓冲区->显示到屏幕上 读取顶点数据指的是将待绘制的图形的顶点数据传递给渲染管线中. 顶点着色器最终生成每个定点的最终位置,执行顶点的各种变换
-
OpenGL ES 矩阵变换及其数学原理详解(五)
引子 向量刻画的是线性空间中的对象. 矩阵刻画的是向量在线性空间中的运动(变换,跃迁),相似矩阵本质上就是同一个线性变换的不同的描述. 在一个线性空间中,选定了一组基,对于任何一个线性变化都可以用一个确定的矩阵来描述 矩阵不仅可以作为线性变换的描述,而且可以作为一组基的描述,作为变换的矩阵,不但可以把线性空间中的一个点给变换到另一个点去,而且也能够把线性空间中的一个坐标系(基)表换到另一个坐标系(基)去. 当我们谈到向量时,一定要指定它所在的坐标系才有意义,比如向量b=(1,2,3)实际上指的是
-
Android开发 OpenGL ES绘制3D 图形实例详解
OpenGL ES是 OpenGL三维图形API 的子集,针对手机.PDA和游戏主机等嵌入式设备而设计. Ophone目前支持OpenGL ES 1.0 ,OpenGL ES 1.0 是以 OpenGL 1.3 规范为基础的,OpenGL ES 1.1 是以 OpenGL 1.5 规范为基础的.本文主要介绍利用OpenGL ES绘制图形方面的基本步骤. 本文内容由三部分构成.首先通过EGL获得OpenGL ES的编程接口;其次介绍构建3D程序的基本概念;最后是一个应用程序示例. OpenGL E
-
Python字典底层实现原理详解
在Python中,字典是通过散列表或说哈希表实现的.字典也被称为关联数组,还称为哈希数组等.也就是说,字典也是一个数组,但数组的索引是键经过哈希函数处理后得到的散列值.哈希函数的目的是使键均匀地分布在数组中,并且可以在内存中以O(1)的时间复杂度进行寻址,从而实现快速查找和修改.哈希表中哈希函数的设计困难在于将数据均匀分布在哈希表中,从而尽量减少哈希碰撞和冲突.由于不同的键可能具有相同的哈希值,即可能出现冲突,高级的哈希函数能够使冲突数目最小化.Python中并不包含这样高级的哈希函数,几个重要
-
HashMap底层实现原理详解
一.快速入门 示例:有一定基础的小伙伴们可以选择性的跳过该步骤 HashMap是Java程序员使用频率最高的用于映射键值对(key和value)处理的数据类型.随着JDK版本的跟新,JDK1.8对HashMap底层的实现进行了优化,列入引入红黑树的数据结构和扩容的优化等.本文结合JDK1.7和JDK1.8的区别,深入探讨HashMap的数据结构实现和功能原理. Java为数据结构中的映射定义了一个接口java.uti.Map,此接口主要有四个常用的实现类,分别是HashMap,LinkedHas
-
Python学习之直方图均衡化原理详解
目录 1.点算子 2.线性灰度变换 3.直方图均衡化 4.代码实战 1.点算子 点算子是两个像素灰度值间的映射关系,属于像素的逐点运算,相邻像素不参与运算.点算子是最简单的图像处理手段,如:亮度调整.对比度调整.颜色变换.直方图均衡化等等. 2.线性灰度变换 线性灰度变换表达为: 其中rk.sk分别为输入.输出点像素灰度值. ▲图2.1 线性灰度变换 当a>1时,输出图像像素灰度范围扩大,图像对比度增强,当a<1时反之.这是因为人眼不易区分相近的灰度值,因此若图像灰度值范围较小,观感上细节不够
-
Apache Doris Join 优化原理详解
目录 背景 & 目标 Doris 数据划分 Partition Bucket Join 方式 总览 Broadcast / Shuffle Join Bucket Shuffle Join Plan Rule Colocate Join Runtime Filter 优化 Join Reorder 优化 Join 调优建议 背景 & 目标 掌握 Apache Doris Join 优化手段及其实现原理 为代码阅读提供理论基础 Doris 数据划分 不同的 Join 方式非常依赖于对 Dor
-
通过HashMap原理详解entrySet中的疑问
目录 HashMap底层变量 put()方法: 2. get(Object key)方法: 3. remove(Object key)方法: 4.entrySet()方法: EntrySet类代码 HashMap底层变量 HashMap的底层的一些变量: transient Node<K,V>[] table; //存储数据的Node数组 transient Set<java.util.Map.Entry<K,V>> entrySet; transient int si
-
Spring AOP的实现原理详解及实例
Spring AOP的实现原理详解及实例 spring 实现AOP是依赖JDK动态代理和CGLIB代理实现的. 以下是JDK动态代理和CGLIB代理简单介绍 JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理. CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类.CGLIB是高效的代码生成包,底层是依靠ASM(开源的Java字节码编辑类库)操作字节码实现的,性能比JDK强. 在Spring中
-
MySQL prepare原理详解
Prepare的好处 Prepare SQL产生的原因.首先从mysql服务器执行sql的过程开始讲起,SQL执行过程包括以下阶段 词法分析->语法分析->语义分析->执行计划优化->执行.词法分析->语法分析这两个阶段我们称之为硬解析.词法分析识别sql中每个词,语法分析解析SQL语句是否符合sql语法,并得到一棵语法树(Lex).对于只是参数不同,其他均相同的sql,它们执行时间不同但硬解析的时间是相同的.而同一SQL随着查询数据的变化,多次查询执行时间可能不同,但硬解
-
前端开发之CSS原理详解
前端开发之CSS原理详解 从事Web前端开发的人都与CSS打交道很多,有的人也许不知道CSS是怎么去工作的,写出来的CSS浏览器是怎么样去解析的呢?当这个成为我们提高CSS水平的一个瓶颈时,是否应该多了解一下呢? 一.浏览器的发展与CSS 网页浏览器主要通过 HTTP 协议连接网页服务器而取得网页, HTTP 容许网页浏览器送交资料到网页服务器并且获取网页.目前最常用的 HTTP 是 HTTP/1.1,这个协议在 RFC2616 中被完整定义.HTTP/1.1 有其一套 Internet Exp
随机推荐
- prototype 学习笔记整理
- delphi7连接mysql5的实现方法
- Python黑魔法@property装饰器的使用技巧解析
- 详解vmvare下安装linux RedHat图解(超详细篇)
- PHP setcookie() cannot modify header information 的解决方法
- Oracle 和 mysql的9点区别
- 使用JQuery FancyBox插件实现图片展示特效
- jQuery学习2 选择器的使用说明
- jQuery 插件封装的方法
- js arguments对象应用介绍
- Bootstrap教程JS插件弹出框学习笔记分享
- Java两个乒乓球队比赛名单问题(判断素数)
- Java函数式编程(六):Optional
- 实例解析Java单例模式编程中对抽象工厂模式的运用
- Android计步功能的实现代码
- 基于JS实现EOS隐藏错误提示层代码
- 基于不要返回null之EmptyFactory的应用详解
- 利用Angular2 + Ionic3开发IOS应用实例教程
- Gradle环境下导出Swagger为PDF的步骤详解
- pandas筛选某列出现编码错误的解决方法