投影变换[转]

 

4. 投影变换

一个投影变换类似于选择一个透镜的焦距,它是三种变换中最复杂的一个。

4.1 视锥(Viewing Frustum 4.2 什么是投影变换? 4.3 设置投影矩阵 4.4 一个“W-Friendly”投影矩阵

 

4.1 视锥pic46.gif (8672 bytes)

  视锥就是场景中的一个三维空间,它的位置由视口的摄像机来决定。这个空间的形状决定了摄像机空间中的模型将被如何投影到屏幕上。透视投影是最常用的一种投影类型,使用这种投影,会使近处的对象看起来比远处的大一些。对于透视投影,

  视锥可以被初始化成金字塔形,将摄像机放在顶端。这个金字塔再经过前、后两个剪切面的分割,位于这两个面之间的部分就是视锥。只有位于视锥内的对象才可见。

视锥由凹视野(

fov-field of view)和前后剪切面的位置来进行定义:

pic47.gif (3047 bytes)

  在上图中,变量

D是从摄像机到空间原点的距离,这个空间是在集合管道的最末端经过视变换得到的空间。要了解变量D如何被用来建立投影矩阵,请看“什么是投影变换?”部分。

 

4.2 什么是投影矩阵?

  投影矩阵是一个典型的缩放和透视矩阵。投影变换将视锥变换成一个直平行六面体的形状。因为视锥的近处比远处小,这样就会对靠近摄像机的对象起到放大的作用,也就将透视应用到了场景当中。

  在视锥中,摄像机与空间原点间的距离被定义为变量D。开始定义透视投影的矩阵时,可以象下面左图这样来使用变量D

pic48.gif (1187 bytes)        pic49.gif (1138 bytes)

  视矩阵将摄像机放置在场景的原点。又因为投影矩阵需要将摄像机放在

(0, 0, -D),那么它就要将向量沿z-轴平移-D的距离,如上面右图所示:

将两个矩阵相乘,得到下面的矩阵:

pic50.gif (1178 bytes)

  下图显示了透视变换如何将一个视锥变换成一个新的坐标空间。注意:锥形体变成了直平行六面体,原点从场景的右上角移到了中心。

pic51.gif (4974 bytes)

  在透视变换中,

x-y-方向的限制是-11z-方向的限制是前表面为0,后表面为1

  这个矩阵基于一定的距离(这个距离是从摄像机到邻近的剪切面)对对象进行平移和旋转,但是它没有考虑到视野(

field-of-view),也没有考虑到对象的z-值可能会相同,从而使深度比较变得困难。下面的矩阵讨论了这一问题,并且调整顶点来说明视口的高宽比例:

pic52.gif (1681 bytes)

  在这个矩阵中,

Zn是临近剪切面的z值。变量whQ的意义如下(注意:fovwfovh表示视口的水平和垂直视野,用弧度标示):

pic53.gif (2085 bytes)

  在程序中,使用视野角度来定义

xy缩放系数比使用视口的水平和垂直尺寸(在摄像机空间中)并不方便多少。下面两式使用了视口的尺寸,并且与上面的公式相等:

pic54.gif (871 bytes)

  在这些公式中,Zn表示邻近的剪切面的位置,变量VwVh表示视口的高和宽。这两个参数与D3DVIEWPORT2结构中的dwWidthdwHeight成员相关。

  不管你使用那个公式,将

Zn值尽量设的大一些是很重要的,因为当z值很接近时,大多数情况下是难以分辨的,由一个取巧的方法,就是在进行深度比较时使用16z-bufferDirect3D中,投影矩阵的第(3,4)元素不能为负数。

  同世界和视变换一样,可以调用

IDirect3DDevice3::SetTransform方法来设置透视变换,详细内容见“设置变换”。

 

4.3 设置投影矩阵

  下面的ProjectionMatrix例程函数又四个输入参数,它们用来设置前后剪切面,和视野的水平与垂直角度。视野角度应该比π弧度(180度)小。

D3DMATRIX ProjectionMatrix(const float near_plane,// distance to near clipping plane
             const float far_plane,// distance to far clipping plane
             const float fov_horiz,// horizontal field of view angle, in radians
             const float fov_vert)// vertical field of view angle, in radians
{
 float h, w, Q;
 w = (float)cot(fov_horiz*0.5);
 h = (float)cot(fov_vert*0.5);
 Q = far_plane/(far_plane - near_plane);
 D3DMATRIX ret = ZeroMatrix();
 ret(0, 0) = w;
 ret(1, 1) = h;
 ret(2, 2) = Q;
 ret(3, 2) = -Q*near_plane;
 ret(2, 3) = 1;
 return ret;
} // end of ProjectionMatrix()

  一旦创建完了矩阵,你需要调用

IDirect3DDevice3::SetTransform方法来设置它,同时将第一个参数设置为D3DTRANSFORMSTATE_PROJECTION。详细内容见“设置变换”。

 

4.4 一个W-Friendly投影矩阵

  一个顶点经过世界、观察和投影变换之后,Direct3D立即模式可以利用这个顶点的W成分执行雾化效果,并在深度缓冲中执行基于深度的运算。这样的运算需要投影矩阵将W规范化等价于世界空间的Z。简而言之,如果你的投影矩阵的(3,4)系数不是1,那么你就必须用(3,4)系数的倒数对所有的系数进行缩放。如果没有提供一个适当的矩阵,那么雾化效果和深度缓冲就不能得到正确运用。(“什么是投影矩阵?”中提供的矩阵是适合于)基于W的运算的。)

  下图展示了一个不适合的投影矩阵,和一个经过缩放的适合的矩阵:

pic55.gif (4266 bytes)

  在前面的矩阵中,所有的变量都被假定为非零。有关雾化的内容见“目相关对基于

Z的深度”。有关基于W的深度缓冲见“什么是深度缓冲?”

  注:Direct3D在基于W的深度运算时使用当前设置的投影矩阵。因此,程序必须设置一个适合的矩阵来的导向要的基于W的特性,即使它们没有使用Direct3D变换管道。

转载于:https://www.cnblogs.com/microsoftxiao/archive/2006/03/27/360295.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

那些把天聊死的神操作。。| 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅【1】【2】【3】【4】【5】【6】【7】【8】【9】【10】【11】【12】(图源网络,侵权删)有话请“直”说↓ ↓ ↓

SqlDataReader对象的NextResult方法读取存储过程多个结果集

如上图,我这里有返回4个记录集,分别表示 发送的总数,成功数,失败数,以及所有的记录集,那么我怎么去获取呢? 如果我第二个记录集 第三个记录集 都是多行的话,怎么办?可以参考下面这张…

全部换新-微软复兴.NET,C#10 .NET6 VS2022各个强势!

VS2022.NET6C#10一起体验是啥感觉?爽!令人印象深刻的是VS2022打开超大项目的流畅,.NET6极致简化的MiniAPI框架,C#10各种炫酷新语法。看看下图的代码你能认识吗?来自MiniAPI框架,直接在MapGet里面使用Lambda…

linux 修复图形界面,图形界面操作的备份和恢复Linux发行版

原标题:图形界面操作的备份和恢复Linux发行版来自:Linux迷链接:https://www.linuxmi.com/redo-rescue-2-0-6-linux.html现在可以下载Redo Rescue 2.0.6备份和恢复Linux发行版,该发行版增加了各种改进和新功能以及常见的错误修复。…

汇编语言的Hello World

汇编语言的Hello World,汇编语言没有我想象的那么低级,它已经具备了不少高级语言的特性,代码也变得清晰,层次清楚,易于维护了。a.asm.386.model flat,stdcall includelib kernel32.lib includelib user32.lib MessageB…

一条线一万美元的故事误导了你多少年

全世界只有3.14 % 的人关注了青少年数学之旅福特公司请斯坦门茨检修电机,画一道线用了一万美元,这个几乎人尽皆知的故事告诉我们一个道理:知识就是财富。故事讲到这里就结束了,但实际上,故事还有下文……20世纪初&…

ylbtech-Model-Account(通用账户模块设计)

ylbtech-DatabaseDesgin:ylbtech-Model-Account(通用账户模块设计)ylbtech-Model-Account(通用账户模块设计) 1.A,数据库关系图(Database Diagram)1.B,数据库设计脚本(Database Design Script)-- -- 用户模块设计 -- 2013-8-24 -- author:yuanbo -- US…

祝大家圣诞节快乐

同时庆祝 JWFD 20周年

刘敏:优麒麟开源操作系统运营实践 | DEV. Together 2021 中国开发者生态峰会

内容来源:2021 年 6 月 5 日,由 SegmentFault 思否主办的 2021 中国开发者生态峰会圆满落幕。会上,优麒麟开源社区运营负责人刘敏发表了主题为《优麒麟开源操作系统运营实践》的演讲,从市场的角度去讲解了一些其他板块的知识。分享…

拖延的本质是逃避!| 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅(图源网络,侵权删)扎心了↓ ↓ ↓

C# 无意间写了一段线程死锁的代码

源码如下&#xff1a;private void action_Click(object sender, RoutedEventArgs e){Task t new Task(() >{for (int i 0; i < 10; i){Thread.Sleep(1000);this.Dispatcher.Invoke(() >{lblStr.Content i.ToString();});manualResetEvent.Set();Console.WriteLine…

5G已来,你能做些什么?

5G大潮虽然已经来临&#xff0c;即便没有5G手机&#xff0c;小木还是要不甘示弱地测一下自己的网速&#xff0c;假装自己也是可以美美地在网上冲浪的&#xff01;小木的网速网友提供的5G测速多么痛的领悟&#xff0c;这差距还真的是很大&#xff01;说了这么多&#xff0c;你可…

java得到文件创建时间linux,linux java获取文件创建时间

linux java获取文件创建时间[2021-01-31 07:35:22] 简介:服务器背景有时候我们需要获取文件的创建时间。例如:我在研究 《xtrabackup 原理图》的时候&#xff0c;想通过观察确认 xtrabackup_log 是最php去除nbsp的方法&#xff1a;首先创建一个PHP代码示例文件&#xff1b;然后…

认识WPF

新开一节WPF桌面开发的讲解&#xff0c;这节先初步认识一下什么是WPF。1.简介WPF是 Windows Presentation Foundation 的英文缩写&#xff0c;意为“窗体呈现基础”&#xff0c;是微软基于.NET Framework 3.0 推出的新一代构建窗体程序的框架。不同于WinForm&#xff0c;WPF实现…

MFC Attach()函数和Detach()函数

一、Windows对象和MFC对象的区别&#xff1f;MFC对象实际上并没有把整个Windows对象都包装在其中。对于窗口&#xff1a;MFC对象它只是有一个窗口句柄而已&#xff0c;这个窗口句柄如果指向一个实际存在的窗口对象&#xff08;窗口对象&#xff0c;也就是WNDCLASS&#xff0c;是…

用“谬论”指挥研究方向数十年,是谁让“老年痴呆”至今仍是绝症?

全世界只有3.14 % 的人关注了青少年数学之旅阿尔兹海默症&#xff0c;是“老年痴呆”的正确科学名称。它可能是世界上最广为人知的“绝症”之一&#xff1a;不仅让患者丧失了记忆和自我&#xff0c;也一直令在寻找治疗方法的学者和医药企业束手无策。30 多年前出现的“淀粉样蛋…

一定要多角度看事物 | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅一定要多角度看事物岁月对我们做了什么无法反驳论发型的重要性坐骨神经痛被赋予了新含义老师真的很会总结了&#xff08;图源E_Volution_&#xff09;扎心了↓ ↓ ↓

烧录imx6需要的linux空间,IMX6Q学习笔记——开发板的Linux系统更新和烧录

IMX6Q学习笔记——开发板的Linux系统更新和烧录记录自己在电鱼电子开发SAIL-IMX6Q全能板后&#xff0c;并且对系统和模块进行简单测试的过程之后对开发板的Linux系统进行更新和烧录的记录过程&#xff0c;算是进行一个分享和记录&#xff0c;同时也方便自己日后查阅。首先准备好…

ABP Framework:移除 EF Core Migrations 项目,统一数据上下文

原文&#xff1a;Unifying DbContexts for EF Core / Removing the EF Core Migrations Project[1]导读&#xff1a;软件开发的一切都需要平衡在 ABP Framework V4.4 RC 新增功能介绍 中&#xff0c;对应用程序启动解决方案模板做了一个重要改变&#xff1a;删除 EntityFramewo…

Hello Python

2019独角兽企业重金招聘Python工程师标准>>> My first Python demo>>> movies["a","b","c"] >>> print(movies[0]) a >>> print(movies[1]) b >>> >>> print(movies) [a, b, c…