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 ...
随机推荐
- JavaScript原型链问题
1. 使用new来创建对象(调用构造函数)时,如果return的是非对象(数字.字符串.布尔类型等)会忽而略返回值;如果return的是对象,则返回该对象. 2. 重写原型会切断原型链: foo = ...
- eval 与 Function
var json='{"name":"lee","age":"15"}' function test () { var ...
- Python3.5连接Mysql
由于mysqldb目前仅支持到python3.4,所以这里选择pymysql. pymysql下载地址: https://pypi.python.org/packages/source/P/PyMyS ...
- mvc 扩展htmlhelper
using System.Web.Mvc; namespace System.Web.Mvc{ public static class HtmlExtend { public ...
- CSS成长之路----知识点篇
一,ul--li列表水平排列,切居中对齐 主要是利用Li标签中的display属性.设置为display:inline,使li纵向排布,且能够使用text-align:center;使其居中显示 HT ...
- Example Microprocessor Register Organizations
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION
- 如何真正抓住微信小程序的红利? 阿禅知乎live总结
微信App定义 为满足用户某种开发需求.完全基于微信的消息或网页应用,入口是公众号,用户无需离开微信即可完成所有操作,所有需求都在公众号里被满足 微信App的优势 1. 顾客在哪里,就让顾客在哪里看到 ...
- ls 只显示目录
只显示目录: ls -d */ 在实际应用中,我们有时需要仅列出目录,下面是 4 种不同的方法. 1. 利用 ls 命令的 -d 选项: $ ls -d */ 2. 利用 ls 命令的 -F 选项: ...
- LeetCode Missing Ranges
原题链接在这里:https://leetcode.com/problems/missing-ranges/ 题目: Given a sorted integer array where the ran ...
- Android onMeasure方法介绍
onMeasure方法在控件的父元素正要放置它的子控件时调用.它会问一个问题,“你想要用多大地方啊?”,然后传入两个参数——widthMeasureSpec和heightMeasureSpec. 它们 ...