SharpGL学习笔记(四) 正射投影

上节谈到投影变换分为透视投影(perspective projection)和正射投影(orthographic projection)两种.

透视投影我们已经介绍过了, 现在谈谈正视投影.

正射投影,又叫平行投影.这种投影是一个矩形长方体的平行管道. 它最大的特点是, 无论物体距离相机多远投影后的物体大小尺寸不变.

正视投影函数有两个, 一个是Ortho, 原形如下:

Ortho(double left, double right, double bottom, double top, double near, double far)

其参数 left,right,bottom, top的意义见下图所示.

near, far 可以认为是Z轴方向上的近裁剪平面和远裁剪平面.

笔者为了理解什么是正射投影以及Ortho函数的效果, 在网上翻遍了资料, 都是笼统的文字叙述, 或者是表达有误. 甚至找不到一个直观示意效果图.

后来还是在3dsmax的摄像机属性中看到了"正交投影" 这个属性.  在3dsmax和autoCAD中, Ortho这个单词都被翻译为"正交". 因此"正交"和"正射"表达的是一个东西.

事实证明, 有了3dsmax这样的工具, 可以有效的实践一些原理上的东西, 确实对学习OpenGL很有帮助.

请看下面的实验, 它帮助笔者理解了什么是正射投影? 它的效果是怎么样的? 这样的疑惑.

下图是在3dsmax创建的一个场景:
 注意其Camera01视图,  它显示的是摄像机在透视投影下看到一个立方体(线框显示)

同样的场景, 把摄像机改为"正交投影", 可以看到现在的立方体完全没有了透视效果. 这是因为这立方体相当于放置在一个矩形长方体管道中, 投影完全平行, 没有了像透视投影那样的角度发散的效果.

这就是正射投影的最大特点: 无论物体距离相机有多远投影后的物体大小尺寸不变.

下面我们用代码来继续讨论一下Ortho() 函数.

先上个透视投影的效果图, 如下:

这个三角形是画在Z为0的世界坐标系平面上的, 因此LookAt的前三个参数设置0,0,1, 表示摄像机xy指向世界坐标系原点, 摄像机的Z向世界坐标系统的Z正方向走1个单位, 即远离了三角形一个单位, 因此我们能看到三角形了.

现在我们把Perspective改为Ortho.

gl.Ortho(-2, 2, -3,3, -2, -5);
gl.LookAt(0, 0, 1, 0, 0, -10, 0, 1, 0);

跑起来, 屏幕上什么都没有.

这是因为LookAt的第三个参数eyez, 没有位于Ortho参数near和far(即-2, -5)之间的原因.

gl.LookAt(0, 0, -3, 0, 0, -10, 0, 1, 0);

eyez改为-3就可以看到三角形了.

我来总结一下:

经过 gl.Ortho(-2, 2, -3,3, -2, -5) 正射投影之后, 三角形就被置于这个矩形长方体(-2, 2, -3,3, -2, -5)的坐标系中了, 以后LooAt 就是在看这个矩形长方体坐标系中的内容, 如果摄像机的视点设置有超出这个长方体的部分将看不到, 相当于被剪切了.

另外一个函数是 Ortho2D(), 它和Ortho不同的是缺少最后两上参数Near, Far, 这个Ortho2D()实际上是默认near为-1, far为1的Ortho()函数.

笔者并不清楚它有什么作用, 如果以后遇到好的例子, 我会在这里续写这个知识点.

本节源代码直接使用上节的源码

时间: 2024-08-25 11:18:53

SharpGL学习笔记(四) 正射投影的相关文章

SharpGL学习笔记(七) OpenGL的变换总结

笔者接触OpenGL最大的困难是: 经常调试一份代码时, 屏幕漆黑一片, 也不知道结果对不对,不知道如何是好! 这其实就是关于OpenGL"变换"的基础概念没有掌握好, 以至于对"将三维体正确的显示在屏幕上指定位置"这样的操作都无法完成. OpenGL变换包括计算机图形学中最基本的三维变换,即几何变换.投影变换.裁剪变换.视口变换,以及针对OpenGL的特殊变换概念理解和用法,如相机模拟.矩阵堆栈等,这些基础是开始真正走进三维世界无法绕过的基础. 所以笔者在前面花了

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能 说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双向的所以我们想动态的实现多语言切换很是方便今天我做一个小demo给大家提供一个思路 先看一下效果 点击英文  变成英文状态点chinese就会变成中文                          源码的下载地址在文章的最下边 多语言用的是资源文件建

代码管理工具 --- git的学习笔记四《重新整理git(1)》

1.创建版本库 mkdir  创建目录 cd  地址,到该地址下 pwd 显示当前目录 1.创建目录 $ mkdir startGit $ cd startGit $ pwd 显示当前目录 或者cd到桌面,然后再创建目录 2.初始化版本库 $ git init 初始化仓库 提示信息:Initialized empty Git repository in /Users/xingzai/Desktop/startGit/.git/ 建立一个空的git仓库在/Users/xingzai/Desktop

Linux学习笔记四:Linux的文件搜索命令

1.文件搜索命令  which 语法:which [命令名称] 范例:$which ls  列出ls命令所在目录 [[email protected] ~]$ which ls alias ls='ls --color=auto' /bin/ls 另外一个命令:whereis [名称名称],也可以列出命令所在目录. [[email protected] ~]$ whereis ls ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/ma

小猪的数据结构学习笔记(四)

小猪的数据结构学习笔记(四) 线性表之静态链表 --转载请注明出处:coder-pig 本章引言: 在二,三中中我们分别学习了顺序表中的线性表与单链表,线性表有点类似于 我们前面所学的数组,而单链表使用的最多的是指针,这里问个简单的问题, 如果是在以前没有指针的话,前辈先人们怎么实现单链表呢?大家思考下! 没有指针,那么用什么来代替呢?前辈先人们非常机智,想出了使用下标+游标的方式 来实现单链表的效果!也就是今天要讲的--静态链表! 当然你也可以直接跳过本章,因为有了单链表就没有必要用静态链表了

Swift学习笔记四:数组和字典

最近一个月都在专心做unity3d的斗地主游戏,从早到晚,最后总算是搞出来了,其中的心酸只有自己知道.最近才有功夫闲下来,还是学习学习之前的老本行--asp.net,现在用.net做项目流行MVC,而不是之前的三层,既然技术在更新,只能不断学习,以适应新的技术潮流! 创建MVC工程 1.打开Visual studio2012,新建MVC4工程 2.选择工程属性,创建MVC工程 3.生成工程的目录 App_Start:启动文件的配置信息,包括很重要的RouteConfig路由注册信息 Conten

NLTK学习笔记(四):自然语言处理的一些算法研究

自然语言处理中算法设计有两大部分:分而治之 和 转化 思想.一个是将大问题简化为小问题,另一个是将问题抽象化,向向已知转化.前者的例子:归并排序:后者的例子:判断相邻元素是否相同(与排序). 这次总结的自然语言中常用的一些基本算法,算是入个门了. 递归 使用递归速度上会受影响,但是便于理解算法深层嵌套对象.而一些函数式编程语言会将尾递归优化为迭代. 如果要计算n个词有多少种组合方式?按照阶乘定义:n! = n*(n-1)*...*1 def func(wordlist): length = le

Android学习笔记四:添加Source

问题描述 Source not foundThe JAR file D:\.....\sdk\platforms\android-20\android.jar has no source attachment. 问题原因及解决办法 1. 使用SDK Manager下载最新版本的Sources for Android SDK 一般文件下载目录默认在SDK下的sources文件中即 \adt-bundle-windows-x86_64-20130522\sdk\sources\android-20

【Unity 3D】学习笔记四十二:粒子特效

粒子特效 粒子特效的原理是将若干粒子无规则的组合在一起,来模拟火焰,爆炸,水滴,雾气等效果.要使用粒子特效首先要创建,在hierarchy视图中点击create--particle system即可 粒子发射器 粒子发射器是用于设定粒子的发射属性,比如说粒子的大小,数量和速度等.在创建完粒子对象后,在右侧inspector视图中便可以看到所有的粒子属性: emit:是否是使用粒子发射器. min size:粒子最小尺寸. max size:粒子最大尺寸. min energy:粒子的最小生命周期