视图变换
在opengl中,视图变换的输入是:
(1)眼睛位置(或者说相机位置)eys;
(2)眼睛朝向的中心center,(就是眼睛朝哪里看);
(3)头的方向up。
任何一点经过视图变换后都会转化到眼睛坐标系下。具体地说,眼睛坐标系的三个轴分别是:
(1)z轴: F=center-eye;(要归一化)
(2)x轴: S=cross(F,up);(这里是叉乘,也要归一化)
(3)y轴: U=cross(S,F)。
此时,eye的位置就是原点了。那么对于任意一点P(px,py,pz),在新坐标下的三个点分别是:
px=dot(p-eye,S);(这里是点乘)
py=dot(p-eye,U);
pz=dot(p-eye,F)

所以可得变换矩阵为:

不过在opengl的坐标系下。z轴的方向其实是垂直屏幕向外的,所以与我们上面的F是相反的。因此实际的变换矩阵是下面这样子:

这样的变换矩阵,其实对于真正能看到的点,变换后它的z坐标应该是一个负的值。

透视投影

透视投影的输入为
(1)宽度width
(2)高度height
(3)近裁面near
(4)远裁面far。
经过透视投影变换后的点的坐标,xyz都在[-1,1]。(不在这个范围内的将被opengl裁剪掉)。而且这里输入的点一般是经过视图变换的点,因此点的z坐标是个负值。

如上图所示,设一个点的坐标是(x,y,z),变换之后的坐标为$(x_{proj},y_{proj},z_{near})$。那么由三角形相似可得:

$\frac{z_{near}}{-z}=\frac{y_{proj}}{y}=\frac{x_{proj}}{x}$

所以

$y_{proj}=\frac{z_{near}\cdot y}{-z}$

$x_{proj}=\frac{z_{near}\cdot x}{-z}$
然后将$y_{proj},x_{proj}$变换到[-1,1]之间,即$y_{proj}=\frac{z_{near}\cdot y}{-z\cdot width/2}$,$x_{proj}=\frac{z_{near}\cdot x}{-z\cdot height/2}$。

下面我们来讨论变换后的z坐标。由于在远裁面将被映射到1,近裁面将被映射到-1,设z的变换公式为$f(z)=\frac{Az+B}{-z}$,$-z$的意思是最后的齐次坐标是$-z$,归一化的时候用的是$-z$。那么有:$\left\{\begin{matrix}\frac{A(-\cdot z_{near})+B}{-(-z_{near})}=-1\\ \frac{A(-\cdot z_{far})+B}{-(-z_{far})}=1\end{matrix}\right.$
解得:$\left\{\begin{matrix}A=-\frac{z_{near}+z_{far}}{z_{far}-z_{far}}\\ B=-\frac{2z_{near}z_{far}}{z_{far}-z_{near}}\end{matrix}\right.$
令$X=\frac{z_{near}}{width/2} $,$Y=\frac{z_{near}}{height/2} $最后得到变换矩阵为:
$\begin{bmatrix}X & 0 & 0 & 0 \\ 0 & Y & 0 & 0 \\ 0 & 0 & A & -1\\ 0 & 0 & B & 0\end{bmatrix}$

另外,有时候计算透视投影时输入是长宽比aspect和视野的角度Fov(y轴的角度)。这里可以想办法计算出width和height的表达式,带入上面的变换矩阵。过程略去了。最后计算的$X=\frac{1}{aspect\cdot tan(\frac{Fov}{2})}$,$Y=\frac{1}{tan(\frac{Fov}{2})}$

正交投影

正交投影的输入为left,right,top,bottom,far,near。
对于x方向来说,设插值方程为$fx(x)=Ax+B$,那么有:$\left\{\begin{matrix}A \cdot left +B=-1\\ A \cdot right +B=1\end{matrix}\right.$,解得:$\left\{\begin{matrix}A=\frac{2}{right-left}\\ B=-\frac{right+left}{right-left}\end{matrix}\right.$

y方向同理。

对于z方向来说,$fz(-near)=-1,fz(-far)=1$。

最后得到变换矩阵为:
$\begin{bmatrix}Ax & 0 & 0 &0 \\ 0 & Ay & 0 &0 \\ 0 & 0 & Az & 0\\ Bx & By& Bz &1 \end{bmatrix}$

其中

$Ax=\frac{2}{right-left}$

$Bx=-\frac{right+left}{right-left}$

$Ay=\frac{2}{top-bottom}$

$By=-\frac{top+bottom}{top-bottom}$

$Az=-\frac{2}{far-near}$

$Bz=-\frac{far+near}{far-near}$

opengl视图变换 投影变换推导的更多相关文章

  1. 视图矩阵的推导-opengl应用

    把物体从世界坐标系转化到视点坐标系的矩阵称为视图矩阵. 下面我们先看下opengl视图矩阵的推导过程: 假设视点或camera的局部坐标系为UVN,UVN分别指向右方.上方和后方从而构成右手坐标系,视 ...

  2. OpenGL的视图变换、模型变换、投影变换、视口变换

    产生目标场景的过程类似于用照相机进行拍照: (1) 把照相机固定在三角架上,并让他对准场景从不同位置观察场景(视图变换) gluLookAt (2) 对场景进行安排,使各个物体在照片中的位置是我们所希 ...

  3. OpenGl学习笔记3之模型变换、视图变换、投影变换、视口变换介绍

    模型变换.视图变换.投影变换.视口变换介绍 opengl中存在四种变换,分别是模型变换,视图变换,投影变换,视口变换.这四种变换是图形渲染的基本操作,实质上这四种变换都是由矩阵乘法表示(这些操作都是由 ...

  4. OpenGL模型视图变换、投影变换、视口变换的理解

    OpenGL中不设置模型,投影,视口,所绘制的几何图形的坐标只能是-1到1(X轴向右,Y轴向上,Z轴垂直屏幕向外). 产生目标场景的过程类似于用照相机进行拍照: (1)把照相机固定在三角架上,并让他对 ...

  5. 详解OpenGL中的各种变换(投影变换,模型变换,视图变换)(完)——法线变换

    前面两节内容已经说完了所有的三种变换.也就是说我们现在程序里面既不需要glLookAt(),也不需要gluPerspective(),这些矩阵我们都可以自己写.然后,再用glMultMatrix()来 ...

  6. WebGL简易教程(五):图形变换(模型、视图、投影变换)

    [toc] 1. 概述 通过之前的教程,对WebGL中可编程渲染管线的流程有了一定的认识.但是只有前面的知识还不足以绘制真正的三维场景,可以发现之前我们绘制的点.三角形的坐标都是[-1,1]之间,Z值 ...

  7. OpenGL学习笔记4——模型视图变换

    以日月地为例的一个模型视图变换.绕了比较多的弯路,下面是几个注意点总结. 注意点: 1.GL函数对模型的操作是基于当前局部坐标系,即模型坐标系而非世界坐标系,二者只在第一次初始化完毕之后才重合: 2. ...

  8. View Transform(视图变换)详解

    http://www.cnblogs.com/graphics/archive/2012/07/12/2476413.html 什么是View Transform 我们可以用照相机的原理来阐释3D图形 ...

  9. 齐次坐标概念&&透视投影变换推导

    http://daehgib.blog.163.com/blog/static/1861071422011579551134/ 透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(fr ...

随机推荐

  1. 20145334实验三《敏捷开发与XP实践》

    实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验步骤 1.敏捷开发与XP 敏捷开发(Agile Dev ...

  2. 关于struts2上传图片临时文件

  3. session生命周期

    session生命周期 原文链接:http://blog.sina.com.cn/s/blog_72c8c1150100qpgl.html 文中黄色字体为我的标记修改或添加 Session保存在服务器 ...

  4. 对struct和class使用大括号初始化的测试

    #include <iostream> using namespace std; struct struct1{ /* struct1(){ cout<<"this ...

  5. Beta阶段站立会议-01

    组名:金州勇士 组长:尹良亮 组员:王汉斌.杜月.闫浩楠 代码地址: ssh:git@git.coding.net:handsomeman/examm.githttps://git.coding.ne ...

  6. str_replace() 用法bug和技巧

    语法 str_replace(find,replace,string,count) 参数 描述 find 必需.规定要查找的值. replace 必需.规定替换 find 中的值的值. string ...

  7. php实现单个用户禁止重复登录,防止同一用户同时登陆

    <?php session_start(); //ini_set('session.auto_start', 0); //关闭session自动启动 //ini_set('session.coo ...

  8. Unity3D 开发 之 加载Android应用的环境

    (1)下载安装JDK:http://www.oracle.com/technetwork/java/javase/downloads/index.html (2)下载安装Android SDK:htt ...

  9. 前后端分离开发——模拟数据mock.js

    mock.js 生成模拟数据,拦截ajax请求 <script type="text/javascript" src="http://libs.baidu.com/ ...

  10. 启动Hive报错

    Exception in thread "main" java.lang.RuntimeException: Hive metastore database is not init ...