opengl视图变换 投影变换推导
视图变换
在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视图变换 投影变换推导的更多相关文章
- 视图矩阵的推导-opengl应用
把物体从世界坐标系转化到视点坐标系的矩阵称为视图矩阵. 下面我们先看下opengl视图矩阵的推导过程: 假设视点或camera的局部坐标系为UVN,UVN分别指向右方.上方和后方从而构成右手坐标系,视 ...
- OpenGL的视图变换、模型变换、投影变换、视口变换
产生目标场景的过程类似于用照相机进行拍照: (1) 把照相机固定在三角架上,并让他对准场景从不同位置观察场景(视图变换) gluLookAt (2) 对场景进行安排,使各个物体在照片中的位置是我们所希 ...
- OpenGl学习笔记3之模型变换、视图变换、投影变换、视口变换介绍
模型变换.视图变换.投影变换.视口变换介绍 opengl中存在四种变换,分别是模型变换,视图变换,投影变换,视口变换.这四种变换是图形渲染的基本操作,实质上这四种变换都是由矩阵乘法表示(这些操作都是由 ...
- OpenGL模型视图变换、投影变换、视口变换的理解
OpenGL中不设置模型,投影,视口,所绘制的几何图形的坐标只能是-1到1(X轴向右,Y轴向上,Z轴垂直屏幕向外). 产生目标场景的过程类似于用照相机进行拍照: (1)把照相机固定在三角架上,并让他对 ...
- 详解OpenGL中的各种变换(投影变换,模型变换,视图变换)(完)——法线变换
前面两节内容已经说完了所有的三种变换.也就是说我们现在程序里面既不需要glLookAt(),也不需要gluPerspective(),这些矩阵我们都可以自己写.然后,再用glMultMatrix()来 ...
- WebGL简易教程(五):图形变换(模型、视图、投影变换)
[toc] 1. 概述 通过之前的教程,对WebGL中可编程渲染管线的流程有了一定的认识.但是只有前面的知识还不足以绘制真正的三维场景,可以发现之前我们绘制的点.三角形的坐标都是[-1,1]之间,Z值 ...
- OpenGL学习笔记4——模型视图变换
以日月地为例的一个模型视图变换.绕了比较多的弯路,下面是几个注意点总结. 注意点: 1.GL函数对模型的操作是基于当前局部坐标系,即模型坐标系而非世界坐标系,二者只在第一次初始化完毕之后才重合: 2. ...
- View Transform(视图变换)详解
http://www.cnblogs.com/graphics/archive/2012/07/12/2476413.html 什么是View Transform 我们可以用照相机的原理来阐释3D图形 ...
- 齐次坐标概念&&透视投影变换推导
http://daehgib.blog.163.com/blog/static/1861071422011579551134/ 透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(fr ...
随机推荐
- Android课程---表格布局TableLayout
特别注意:由于表格布局继承自线性布局,因此并不显示表格线 示例代码: <?xml version="1.0" encoding="utf-8"?> ...
- IOS第八天(7:UITableViewController新浪微博,cell 复用的简单写法优化和cell高度从模型中获取)
*********** #import "HMViewController.h" #import "HMStatus.h" #import "HMSt ...
- 【iCore3 双核心板】例程十二:通用定时器实验——定时点亮LED
实验指导书及代码包下载: http://pan.baidu.com/s/1kTWAAJ9 iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- Java简单类——双向一对多映射
class Item { // 父栏目 private int iid ; private String name ; private String note ; private Subitem su ...
- Erlang使用相关笔记
#从源码编译安装Erlang 1. wget http://www.erlang.org/download/otp_src_r16b.tar.gz -p /usr/local/src 2. tar z ...
- QMessageBox
#include "dialog.h" #include "ui_dialog.h" #include<QMessageBox> Dialog::D ...
- LeetCode Minimum Height Trees
原题链接在这里:https://leetcode.com/problems/minimum-height-trees/ 题目: For a undirected graph with tree cha ...
- Win10如何设置防火墙开放特定端口 windows10防火墙设置对特定端口开放的方法
Win10防火墙虽然能够很好地保护我们的系统,但同时也会因限制了某些端口,而给我们的操作带了一些不便.对于既想使用某些端口,又不愿关闭防火墙的用户而言,在Win10系统中设置防火墙开放特定端口就非常必 ...
- lua2c
lua2c lua2c is a Lua module and utility to convert Lua 5.1 source code to C API code. http://lua-use ...
- Maven聚合与继承的实例讲解(二)
继续上一节讲Maven的内容,我们这个节继续讲Maven继承和聚合的其他内容. 现在我们新建一个实例来测试Maven有关于聚合的部分 测试开始 一.建立以pom为packaging的项目 ...