【WPF】三维模型中的“照相机”
WPF 部分支持三维模型,为啥说是部分支持?毕竟 WPF 的侧重点还是在应用开发上,虽然也有些游戏是用 WPF 开发的,不过,老周想啊,如果真要开发游戏,最好用专门的框架,WPF 应当用于开发应用功能的。不过,动画、三维建模这些支持可以作为辅助,尤其是在 UI 上,适当地,可以增强一下。当然,不要为了装逼,弄得不伦不类的,那样就是主次不分了,现在有不少软件就是主次不分的。
在 WPF 中,要呈现三维模型,需要用到 Viewport3D ,它是三维对象的总容器,所有三维对象都应该放在这个容器中。本文老周不介绍三维对象的树结构,而是重点说说 Viewport3D 的一个重要配件——照相机。
其实,这个“照相机”,与我们现实世界中的照相机差不多,它是我们观察三维模型的一个入口,就好比我们从真实相机中的取景器去观察被摄对象一样,由于相机的视角广度有限(哪怕是广角镜头也是有限的),现实的被摄物体可以无限延展,但是,你在取景器中看到的只能是局部。道理也是一样的,在 WPF 的三维模型中,Camara 只是设定我们能看到三维对象的局部,而维对象本身也可能是无限延展的。
Viewport3D 对象有个 Camera 属性,用来设置一个合适的相机实例。照相机可以分为两大类:
第一类,MatrixCamera,它通过一个矩阵来描述照相机的参数,这个估计用得不多,因为挺复杂的,反正老周是不知道怎么用的。
第二类,ProjectionCamera,即带投影透视效果的照相机,它派生出两款相机,注意啊,不是佳能和尼康,是 PerspectiveCamera 和 OrthographicCamera。PerspectiveCamera相机比较好解,因为它是带透视效果的,这也符合我们灵长目类动物的视觉特征——离得近的物体看起来会大一些,离得远的物体会小一些,当然了,前提是物体大小接近,不然,这太阳比月球大太多了,所以,哪怕太阳离我们更远,看起来也比月亮大。而 OrthographicCamera 呢,它不太符合咱们灵长目动物的视觉特征,因为使用这个照相机后,所视物体就变成了正交,即不存在透视效果,没有距离之别,不管远的还是近的,都一样大。人要是能做到像正交镜头这样就好了,不管亲疏都一视同仁。有时候,人真的还不如代码友好,因为有些人会算计你,但代码不会,虽然有时候,代码会耍性子,让你又爱又恨,但是,它待你是真诚的,而人呢,也许只有少部分人能做得到,社会太缺诚信。
嗯,介绍完了几类照相机,相信大伙一定想看看效果。行,老周也想,要不,咱们试试。
为了简单,老周只建了一个正方体,而且这个正方体是衣裳不整的,只围了一条裙子,仅仅声明了左、前、右三个面。
<Viewport3D>
……
<!-- 模型,三个面 -->
<ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="-2,4,0 -2,0,0 -2,0,4 -2,4,4" TriangleIndices="0,1,2,0,2,3"/>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Green"/>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="-2,4,4 -2,0,4 2,0,4 2,4,4" TriangleIndices="0,1,2,0,2,3"/>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Blue"/>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="2,4,4 2,0,4 2,0,0 2,4,0" TriangleIndices="0,1,2,0,2,3"/>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Red"/>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</ModelVisual3D>
<!-- 灯光,用来照亮模型,不然就全黑一片了 -->
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="Purple" />
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
AmbientLight 指的是环境光,即可以照亮整个模型的光,如果用 PointLight ,就是点光,类似于一个小灯泡,小蜡烛,只能照亮一点点空间。Color属性指定了这灯光是紫色的,紫光可以诱捕害虫,所以就用紫光了。
好,重点来了,我们先看看正交照相机。
<Viewport3D>
<Viewport3D.Camera>
<OrthographicCamera Position="16,2,18" LookDirection="-1,0,-1" Width="10" />
</Viewport3D.Camera>
……
</Viewport3D>
Position 是指定照相机的位置,注意Z轴的坐标,如果Z轴值大于模型的Z轴值,那么镜头就在物体前面,反之在物体后面。因此,你可以设置 LookDirection 来调整相机的方向,Position是相机的位置,就好比你站在某个点拍照;而LookDirection是相机看的方向,就像你拿着相机可以拍你前面的妹子,也可以拍你左边的大爷,或者拍与你成30度夹角处的大叔。LookDirection指定你朝哪儿看。
如果相机位于物体前方,LookDirection 的Z轴值要小于0,因为Z轴的负方向是指向屏幕内部的,只有朝着负方向,才能看到物体;如果相机位于物体背面,那么Z轴的值就要大于0,就样才会朝向屏幕外部,看到物体。
正交相机看到的正方体如下图所示。

这是正方体的前面和侧面,但是,你都看到了,两个面一样大,按理说,正面应该要离我们近一些,但是,正交相机是不考虑这个的,在它眼中,世界都是平的。
下面我们再换一个透视效果的相机。
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera Position="10,5,10" LookDirection="-2.5,-1,-2" />
</Viewport3D.Camera>
……
</Viewport3D>
相机位于物体的左前方,并且朝着物体的右下方观察。
此时,如下图所示,你会看到透视效果。

也许,这个更符合我们在现实世界中的观察效果。
好了,又是开饭时间,今天就聊到这里吧,有空,改天咱们泡上一壶龙井茶,继续聊。
【WPF】三维模型中的“照相机”的更多相关文章
- 在WPF程序中使用摄像头兼谈如何使用AForge.NET控件(转)
前言: AForge.NET 是用C#写的一个关于计算机视觉和人工智能领域的框架,它包括图像处理.神经网络.遗传算法和机器学习等.在C#程序中使用摄像头,我习惯性使用AForge.NET提供的类库.本 ...
- WPF 程序中启动和关闭外部.exe程序
当需要在WPF程序启动时,启动另一外部程序(.exe程序)时,可以按照下面的例子来: C#后台代码如下: using System; using System.Collections.Generic; ...
- 如何在WPF程序中使用ArcGIS Engine的控件
原文 http://www.gisall.com/html/47/122747-4038.html WPF(Windows Presentation Foundation)是美国微软公司推出.NET ...
- WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示
原文:WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示 为方便描述, 这里仅以正方形来做演示, 其他图形从略. 运行时效果图:XAML代码:// Transform.XAML< ...
- WPF/Silverlight中的RichTextBox总结
WPF/Silverlight中的RichTextBox总结 在WPF或者是在Silverlight中有个非常强大的可以编辑的容器控件RichTextBox,有的时间会采取该控件来作为编辑控件.鉴 ...
- WPF程序中App.Config文件的读与写
WPF程序中的App.Config文件是我们应用程序中经常使用的一种配置文件,System.Configuration.dll文件中提供了大量的读写的配置,所以它是一种高效的程序配置方式,那么今天我就 ...
- WPF项目中解决ConfigurationManager不能用(转)
https://blog.csdn.net/MOESECSDN/article/details/78107888 在WPF项目中遇到这样的问题,做一下笔记.希望对自己和读者都有帮助. 在aap.con ...
- wpf自定义控件中使用自定义事件
wpf自定义控件中使用自定义事件 1 创建自定义控件及自定义事件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 2 ...
- VS编程,编辑WPF过程中,点击设计器中界面某一控件,在XAML中高亮突出显示相应的控件代码的设置方法。
原文:VS编程,编辑WPF过程中,点击设计器中界面某一控件,在XAML中高亮突出显示相应的控件代码的设置方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net ...
随机推荐
- Python之路-字符编码&数据类型补充
作业 三级菜单程序 menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{ }, '网易':{ }, 'google':{ } }, '中关村':{ '爱奇艺':{}, '汽车 ...
- MySQL读写分离技术
1.简介 当今MySQL使用相当广泛,随着用户的增多以及数据量的增大,高并发随之而来.然而我们有很多办法可以缓解数据库的压力.分布式数据库.负载均衡.读写分离.增加缓存服务器等等.这里我们将采用读写分 ...
- javascript继承详解(待续)
常见继承分两种,一种接口继承,继承方法签名:一种实现继承,继承实际方法.js只支持后一种. 1原型链 首先看原型.构造函数.实例的关系.如果我们让一个函数的原型对象等于另一个的实例,然后另一个的原型对 ...
- php生成器使用总结
一般我们在迭代一组数据的时候,需要创建一个数据,如果数组很大,则会消耗很大性能,甚至造成内存不足抛出error比如: //Fatal error: Allowed memory size of 134 ...
- 概率检索模型及BM25
概率排序原理 以往的向量空间模型是将query和文档使用向量表示然后计算其内容相似性来进行相关性估计的,而概率检索模型是一种直接对用户需求进行相关性的建模方法,一个query进来,将所有的文档分为两类 ...
- java swing组件的一些基本属性
JLabel get/setText(): 获取/设置标签的文本. get/seticon(): 获取/设置标签的图片. get/setHorizontalAlignment(): 获取/设置文本的水 ...
- php 启动过程 - sapi MINIT 过程
php 启动过程 - sapi MINIT 过程 sapi 概念 sapi 是 php 的应用编程接口, server 端接收请求通过 sapi 接口层交给 php 处理 不同的 server 端底层 ...
- A GDI+ Based Character LCD Control
This is a renew. A GDI+ Based Character LCD Control by Conmajia Character liquid crystal display (LC ...
- Android之AIDL知识总结
1.AIDL介绍 AIDL是一个缩写,全称是Android Interface Definition Language,翻译为Android接口定义语言.主要用于线程之间的通信,本文主要以不同应用之间 ...
- python字符串实战
haproxy配置文件 思路:读一行,写一行 global log 127.0.0.1 local2 daemon maxconn 256 log 127.0.0.1 local2 info defa ...