精华内容
下载资源
问答
  • 不一样视角不一样的VR

    千次阅读 2016-08-10 20:24:34
    其实也并不是想关注VR,只是觉得AR/VR在现在已经被炒的太热了,以至于就好像我们已经完全掌控了它一样。但实际上我们才仅仅开始;或者说,我们还并未真正的开始。此次谷歌大会首推当家虚拟平台Daydream,这个名字...

    # 写在前面

    直到上周,我才跟同事一起看了Google I/O 2016发布会。其实也并不是不想关注VR,只是觉得AR/VR在现在已经被炒的太热了,以至于就好像我们已经完全掌控了它一样。但实际上我们才仅仅开始;或者说,我们还并未真正的开始。

    此次谷歌大会首推当家虚拟平台Daydream,这个名字好,一下子就体现了VR的最重要的特点。大会上,谷歌宣称未来将会发布可以完美运行Draydream的Android手机,并且将会在手机端主推VR体验。会议中,谷歌方的多位大咖谈论了自己对VR的看法,以及VR在众多领域的用武之地。整个大会完全一改以往IT巨头之势,反而走起了清新文艺风,接地气的同时又还是那么的高逼格。

    这次发布会我看了好几遍,也推荐给了许多朋友,因为突然感觉对VR又有了许多新的看法–不仅是好奇它所给我们生活带来的美妙,似乎也有了些许担忧。

    时代的脚步

    “超市购物结账,随手拿出手机,点击微信支付,收银员扫描二维码,付款走人”,这个不到5秒就能操作完成的事情,我想对于当下每个年轻人来说,都是正常生活的一部分。但就是这种简单的类似吃饭的事情,常常都能惊到我身后排队的大妈大爷,他们感叹新生活的变化,他们也随着时代的脚步一起前进,但始终,都无法融入。

    我从来都没有因此而笑话过他们,有时候我只觉得:这个时代的脚步对于他们来说,走的快了些。

    我父母那一代,大多都出生在五六十年代,到现在基本都是60岁上下的人了。他们这一代到今天,经历了太多太多,有时候还未来得及去适应就得去迎接下一个时代--从吃不饱肚子到文化大革命,再从改革开放到走向世界。一直以来,他们都在努力的接受生活的变化。但尤其是最近的十几年,我越发的觉得他们已经被lost的太远太远。究其原因,我觉得可能是互联网这20年,让我们的生活发生了翻天覆地的变化,而父母一辈从未接受过这类新鲜的知识,甚至连拼音都不会,更谈何上网呢。

    还记得互联网兴起(或者说是我接触)那会,大约是90年代后期,一大帮孩子钻到网吧组队去玩CS,年龄稍大点的可能偏爱大话西游等网络游戏。那时候,大多数人并不知道所谓电脑,互联网是什么,只知道我们可以一起玩游戏,这比起游戏厅那确实有意思多了。还依稀记得许多家长经常在网吧打孩子的场景,后来我爸也经常说,买电脑就是给大孩子买了一个玩具。不得不说,那是一个全民网瘾的时代--可是现在想想,在当时,面对这么有诱惑力的东西,而又没有人能告诉你它是什么的时候,你只能深陷其中,独享其乐。

    到了中学时期,突然兴起了个人博客,也有少数人开始逛逛所谓的论坛,更别提那时候收发email是多么的高逼格了。在后来,上了大学,接触了更多互联网所能给我带来的资源--我们一起追校园网上的美剧,我们一起写百度出来的论文,我们一起敲不明觉厉的汇编程序。在这一演变过程中不难看出:我们使用互联网所做的事情不再只是游戏和娱乐那么单一,互联网已经不是那个我们原以为的玩物,而是丰富的足以淹没我们的资源,我们已经似乎慢慢的理解了什么是互联网,以及它给我们所来带的益处。

    迷一般的VR

    虽然VR是承载于计算机互联网之上的,但我还是觉得有必要将两者分开:因为VR技术已经是计算机领域的另一高度了,它的出现就像是互联网在90年代席卷我们的生活一样:我们现在的认知还不足以诠释以后的VR生活,以及他能给我们带来的好处和坏处。我们所能看到的只是VR给我们带来的不一样的视觉享受,不一样的3D体验。

    有时候觉得VR就像是躺在摇篮中的孩子,你时常能够看到它可爱动人的一面,但它长大后的秉性如何,又是谁能够预测的了呢?这就好比我读研期间接触的物联网一样,我觉得它与人工智能一样,前景可观,这些都将是未来改变人类生活的重要技术手段。它们固然有潜在的价值和未来的市场,可它们毕竟还都是孩子,如何成长在是当下最重要的事情。

    未来的生活必然充斥着许多VR体验:我们可以和自己爱慕已久的明星谈恋爱,我们可以参加演唱会而不用亲临现场,我们可以躺在床上周游世界甚至是登陆月球。这些刺激的体验我们称为Virtual Reality,那就说明我们还能够清楚的分辨出和你谈恋爱的那个人是虚拟的,还能够分辨出参加的演唱会并不是真实的,当然也能够分辨出登陆的月球只不过是由大量的卫星图片组成的3D假象。很庆幸,以现在的角度,我们还能够清楚的分辨虚拟和现实。这种VR是我们当下所期盼的,我也不无例外,很希望技术发展的更快一些,这种刺激的体验谁不想尝试一下呢?充其量,我们就还像小时候一样,再次染上了VR瘾,但似乎听起来不但没有网瘾那么糟糕,反而还挺令人期待的。

    可我觉得事实并非如此,记得《奇葩说》里有一期的话题是“爱上人工智能算不算爱情”,我觉得这与我对VR未来的看法如出一辙。

    当有一天,我们的传感器已经不光只能采集到温湿度等简单参数,并且精度大幅度提高,城市中布满了各种网络节点;我们也不再依赖于传统的通信方式,日照灯光即可作为传输媒介;AlphalGo之类的算法也许已经融入到了生活的各个角落,VR也已彻底做到了“Bridge The Gaps Between Virtuality and Reality”。到那时,我们还有什么能力去分辨我们身在何处?我们又如何分辨真实与谎言?

    写在最后

    我能想到的场景可能是这样的:在一个冬季的午后,一位老人缓慢的行走在老城的小巷,旁边搀着的是他的老伴,老人虽然步履蹒跚,但仍是一脸笑容,看起来是如此的幸福。尽管是冬季,可阳光依旧很暖,毫不吝啬的洒在老人的身上,可老人的影子却是那么的孤单。

    展开全文
  • 只要有相应的照片,把视角封闭在一个相对封闭的空间中,我们查看的效果,就达到了全景图的效果。案例我写了一个由六个不同颜色的纹理组成的图片拼接出来的盒子,可以清楚的查看出来效果。地址:...

    简介

    本全景前期是使用六张图片拼成的一个立方体,天空盒类型的。相机的位置处于0,0,0的位置,外面设置了一个长宽高都为200的立方体盒子。只要有相应的照片,把视角封闭在一个相对封闭的空间中,我们查看的效果,就达到了全景图的效果。

    案例

    我写了一个由六个不同颜色的纹理组成的图片拼接出来的盒子,可以清楚的查看出来效果。

    这里写图片描述

    地址:https://johnson2heng.github.io/panorama/examples/02%20cube/index.html

    解析

    当前案例使用的相机是THREE.PerspectiveCamera透视相机,设置的fov为90度,相机设置在了原点,也是盒子的中心点。
    通过以上的信息我们可以分析出来,相机的视角target如果朝向的是一个面的中心点的话,当前面会整个显示在页面当中。
    之前会比较疑惑,由于浏览器宽高比会不一样,那样生成的图形在不变形的情况下,会怎么变化。
    通过案例,我们会发现,其实相机的高度,显示的是标准的fov为90显示的内容,而宽度会根据高度的比例显示内容,如果宽度小于高度,则按fov的百分比显示,如果宽度大于高度,则会显示一部分具有透视效果很大的内容。

    展开全文
  • opengl 视角问题

    千次阅读 2013-07-17 14:47:13
    关于矩阵的知识,这里详细介绍,有兴趣的朋友可以看看线性代数(大学生的话多半应该学过的)。 OpenGL可以在最底层直接操作矩阵,不过作为初学,这样做的意义并不大。这里就做介绍了。 1、模型变换和视图...
    OpenGL变换实际上是通过矩阵乘法来实现。无论是移动、旋转还是缩放大小,都是通过在当前矩阵的基础上乘以一个新的矩阵来达到目的。关于矩阵的知识,这里不详细介绍,有兴趣的朋友可以看看线性代数(大学生的话多半应该学过的)。
    
    OpenGL可以在最底层直接操作矩阵,不过作为初学,这样做的意义并不大。这里就不做介绍了。


    1、模型变换和视图变换
    从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。
    由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:
    glMatrixMode(GL_MODELVIEW);
    通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。这也只需要一行代码:
    glLoadIdentity();

    然后,就可以进行模型变换和视图变换了。进行模型和视图变换,主要涉及到三个函数:
    glTranslate* ,把当前矩阵和一个表示移动物体的矩阵相乘。三个参数分别表示了在三个坐标上的位移值。
    glRotate* ,把当前矩阵和一个表示旋转物体的矩阵相乘。物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数angle表示旋转的角度。
    glScale* ,把当前矩阵和一个表示缩放物体的矩阵相乘。x,y,z分别表示在该方向上的缩放比例。

    注意我都是说“与XX相乘”,而不是直接说“这个函数就是旋转”或者“这个函数就是移动”,这是有原因的,马上就会讲到。
    假设当前矩阵为单位矩阵,然后先乘以一个表示旋转的矩阵R,再乘以一个表示移动的矩阵T,最后得到的矩阵再乘上每一个顶点的坐标矩阵v。所以,经过变换得到的顶点坐标就是((RT)v)。由于矩阵乘法的结合率,((RT)v) = (R(Tv)),换句话说,实际上是先进行移动,然后进行旋转。即: 实际变换的顺序与代码中写的顺序是相反的。 由于“先移动后旋转”和“先旋转后移动”得到的结果很可能不同,初学的时候需要特别注意这一点。
    OpenGL之所以这样设计,是为了得到更高的效率。但在绘制复杂的三维图形时,如果每次都去考虑如何把变换倒过来,也是很痛苦的事情。这里介绍另一种思路,可以让代码看起来更自然(写出的代码其实完全一样,只是考虑问题时用的方法不同了)。
    让我们想象,坐标并不是固定不变的。 旋转的时候,坐标系统随着物体旋转。移动的时候,坐标系统随着物体移动。如此一来,就不需要考虑代码的顺序反转的问题了。

    以上都是针对改变物体的位置和方向来介绍的。如果要改变观察点的位置,除了配合使用glRotate*和glTranslate*函数以外,还可以使用这个函数:gluLookAt。它的参数比较多,前三个参数表示了观察点的位置,中间三个参数表示了观察目标的位置,最后三个参数代表从(0,0,0)到 (x,y,z)的直线,它表示了观察者认为的“上”方向。


    2、投影变换

    投影变换就是定义一个可视空间,可视空间以外的物体不会被绘制到屏幕上。(注意,从现在起,坐标可以不再是-1.0到1.0了!)
    OpenGL支持两种类型的投影变换,即透视投影和正投影。投影也是使用矩阵来实现的。如果需要操作投影矩阵,需要以GL_PROJECTION为参数调用glMatrixMode函数。
    glMatrixMode(GL_PROJECTION);
    通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。
    glLoadIdentity();

    透视投影所产生的结果类似于照片,有近大远小的效果,比如在火车头内向前照一个铁轨的照片,两条铁轨似乎在远处相交了。
    使用glFrustum函数可以将当前的可视空间设置为透视投影空间。其参数的意义如下图:
    http://blog.programfan.com/upfile/200610/20061007151547.gif
    声明:该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。
    也可以使用更常用的gluPerspective函数。其参数的意义如下图:
    http://blog.programfan.com/upfile/200610/2006100715161.gif
    声明:该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

    正投影相当于在无限远处观察得到的结果,它只是一种理想状态。但对于计算机来说,使用正投影有可能获得更好的运行速度。
    使用glOrtho函数可以将当前的可视空间设置为正投影空间。其参数的意义如下图:
    http://blog.programfan.com/upfile/200610/20061007151619.gif
    声明:该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

    如果绘制的图形空间本身就是二维的,可以使用gluOrtho2D。他的使用类似于glOrgho。


    3、视口变换
    当一切工作已经就绪,只需要把像素绘制到屏幕上了。这时候还剩最后一个问题:应该把像素绘制到窗口的哪个区域呢?通常情况下,默认是完整的填充整个窗口,但我们完全可以只填充一半。(即:把整个图象填充到一半的窗口内)
    http://blog.programfan.com/upfile/200610/20061007151639.gif
    声明:该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

    使用glViewport来定义视口。其中前两个参数定义了视口的左下脚(0,0表示最左下方),后两个参数分别是宽度和高度。

    4、操作矩阵堆栈
    介于是入门教程,先简单介绍一下堆栈。你可以把堆栈想象成一叠盘子。开始的时候一个盘子也没有,你可以一个一个往上放,也可以一个一个取下来。每次取下的,都是最后一次被放上去的盘子。通常,在计算机实现堆栈时,堆栈的容量是有限的,如果盘子过多,就会出错。当然,如果没有盘子了,再要求取一个盘子,也会出错。
    我们在进行矩阵操作时,有可能需要先保存某个矩阵,过一段时间再恢复它。当我们需要保存时,调用glPushMatrix函数,它相当于把矩阵(相当于盘子)放到堆栈上。当需要恢复最近一次的保存时,调用glPopMatrix函数,它相当于把矩阵从堆栈上取下。OpenGL规定堆栈的容量至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。因此不必过于担心矩阵的容量问题。
    通常,用这种先保存后恢复的措施,比先变换再逆变换要更方便,更快速。
    注意:模型视图矩阵和投影矩阵都有相应的堆栈。使用glMatrixMode来指定当前操作的究竟是模型视图矩阵还是投影矩阵。
    展开全文
  • 视角的讨论

    千次阅读 2015-04-15 14:49:05
    视角的讨论(转) http://school.ogdev.net/listshow.asp?page=4&typeid=0&categoryid=5&id=0&ListType=2 http://www.docin.com/p-391446142.html&key=%E6%96%9C%E8%A7%86%E6%80%8E%E4%B9%88%E6%B2%BB ...
     
    

    http://school.ogdev.net/listshow.asp?page=4&typeid=0&categoryid=5&id=0&ListType=2

    http://www.docin.com/p-391446142.html&key=%E6%96%9C%E8%A7%86%E6%80%8E%E4%B9%88%E6%B2%BB

    http://www.cnblogs.com/axyz/archive/2011/11/03/2234468.html

    目 录 
    1.1 地图和地表 
    1.2 斜视角游戏中的视角 
    1.3 Tile图片的拼接 
    1.4 不同地表间的过渡 
    1.5 地图数据结构的定义 
    -------------------------------------------------------------------------------- 
    这篇关于斜视角游戏的文章节选于前段时间我根据自己的实践体会写的一篇关于游戏制作的文章。对于其中的观点或者说算法,有的是我自己想出来的,有的是借鉴了其他人的。特别要指出的是“斜视角游戏中的视角”和遮挡问题中的图片修正思想是云风提出的,我只不过是借用了一下,在他的个人网站“云风工作室”上有更详细的说明。另外图1.1是从“风魂”(也是由云风开发)游戏制作库的一个演示程序中抓下来的。 
    一直都想写一些关于游戏制作的东西,但直到最近才完成了一点。想写的原因有很多,但最主要的是自己对游戏制作的热爱。因为热爱它所以我才用心去了解它,因为想要了解它我才知道在中国要想学习游戏制作是多么的困难。没有什么系统、完整的资料和书籍可以参考,完全靠自己零零碎碎得从各种可以获得的资料中拼凑。直到有一天我上了网,我才直到在中国有那么多和我一样有共同志向的人在默默无闻地努力着。最让我感动的是他们能把自己的想法和经验毫无保留地写出来,是其他人从中受益,包括我。这就是为什么我也愿意把我所知道的告诉大家的原因。 
    文章中的想法可能是不成熟的或者低效的,仅仅给有志于游戏制作的人参考。你可以自由地阅读和复制这篇文章,但如果你想把文章发布到你的网站上或者别的什么地方,请保持文章的完整(包括这部分)并事先通知我,我想知道我的文章都到了什么地方。另外如果你有什么好的建议或者想法,欢迎来信讨论。 
    1.1、地图和地表 
    许多斜视角游戏中都使用数组来描述游戏中的地图,在每个地图坐标处的地面情况则称为地表,常见的地表有草地、沙漠、水、石板等等。由于每一块地表都拥有同样的大小,所以地表通常也称为Tile(瓦块)。一个完整的地图就是由许多各种各样的Tile组成的。图1.1就是一个典型的斜视角游戏地图的一部分。 
    可以清楚地看到,在斜视角游戏中,每个Tile并不是正方形的,而是有点扁的菱形。正是这种有点扁的菱形使地面出现了立体的感觉,就好象我们站在空中斜向下一样,斜视角游戏也是因此而得名。这个菱形到底有多扁是由游戏使用的视角大小来决定的。因此在更加深入的讨论地图和地表之前,需要先解释一下斜视角游戏中的视角。


     
    图1.1 典型的斜视角游戏 
    1.2、斜视角游戏中的视角 
    从图1.1 中我们已经可以感觉到该图体现的视觉效果并不是从空中垂直向下看,而是视线和地面之间有一个角度,这个角度就是斜视角游戏中的视角。在不同的游戏中,这个角度的大小可以是不同的。在演示程序中每个Tile的宽是62,高是32,因此使用了30度的视角,如图1.2所示。 
     
    图1.2 斜视角游戏中的视角 
    为什么宽为62,高为32的Tile对应的视角是30度呢?可以这样假设,如果从空中垂直俯视地面,此时投影面(就是显示屏对应的平面,该平面永远与视线垂直)与地面重合,因此每个Tile的宽和高都是实际值62。现在视线和地面的夹角是30度,但投影平面仍然和视线垂直,所以在投影面上每个Tile的高符合下面的公式: 
    投影面上Tile的高 = Tile实际的高 * sin (a); 
    其中a代表视角。于是可以推算如果在投影面上Tile的宽为62,高为32,则视角的大小约为30度。 
    1.3、Tile图片的拼接 
    在前面已经说明了在斜视角游戏中表示地表的Tile是菱形的,但计算机中处理的图片都是矩形的,也就是说只能使用矩形的图片来存放菱形的Tile。这样就出现了一个问题,如何对存放Tile图片进行拼接,才能出现象图1.1那样的效果。图片拼接时出现重叠部分是不可避免的,就象图1.3中显示的一样,但是可以想办法隐藏每个Tile图片的多余部分。 
     
    图1.3 Tile图片的拼接 
    一种方法是在制作每个Tile图片是将多余的部分使用黑色(颜色值为 0)填充,在将Tile绘制到屏幕上前将整个地图区域也使用黑色填充,然后使用异或方式将每幅Tile图片绘制到屏幕上,也就是绘制前先让Tile图片中的每个像素和屏幕上对应像素进行异或运算。由于任何值和0进行异或运算的结果是保持值不便。所以使用这种方式绘制Tile可以保证Tile图片中多余的部分不影响最终的图像。还有一种方法就是将Tile图片作为带有透明颜色的位图处理, 使用镂空位图绘制函数或RLE位图绘制函数进行绘制,这样就可以去除Tile图片中多余部分。在演示程序中使用了后一种方法,而在为演示程序制作地图的地图编辑器中使用了前一种方法来拼接Tile图片。 
    1.4、不同地表间的过渡 
    经常可以看到对一些游戏的评价中有场景逼真这样一条,而在斜视角游戏中要做到场景逼真,除了美工对图片的处理要力求真实以外,还有许多其它难点,其中有一个就是地表间的过渡处理。更通俗的说就是怎样处理草地、沙漠、浅滩、雪地等地表之间的过渡问题,才能使它们之间衔接更加地自然,更加接近真实的情况。 
    仔细观察《帝国时代II》的画面,可以发现该游戏在这个问题上处理地非常好。该游戏使用的方法是专门制作各种地表间衔接的Tile图片,在地图放置某个坐标处的地表时对其周围的地表进行判断,从而决定是否需要处理地 表的衔接,如果要,则选择合适的Tile图片,在必要时还需要改变周围已经放置好的Tile图片。说起来容易,做起来难 。如何决定的Tile图片在内存中的排放顺序和如何根据周围的地表对其进行选择是最大的难点。 
    一是因为Tile的衔接是有方向性的,即草原地表在左边, 沙漠地表在右边和草原地表在右边,沙漠地表在左边是不同的。二是当新放置一个地表时,通常需要改变周围已经放置好的Tile图片,而改变它们时也应该考虑到它们自己四周的Tile图片是否应该发生相应变化。三是当多种类型的地表相互接近时,它们之间的过渡问题将变得更加复杂。 
    在制作斜视角游戏的演示程序时我没有直到一个很好的方法可以解决上面叙述的这几个地表过渡问题。而是采用了一个相对比较简单的方法,使用它虽然不能达到象《帝国时代II》中那样的地表效果,但也能比较自然地处理地表间的过渡。在这种方法中一个很重要的思想就是去除地表衔接时的方向性,而使用混合两种地表内容的Tile图片来表现地表过渡,并根据两种地表占用的百分比使用不同的Tile图片。下面使用草原和荒漠两种地表来说明一下这种处理地表过渡的方法。 
    在地图上,除了边沿一圈的坐标,其它每个坐标的周围都有另外8个坐标,也就是说处理某个坐标处使用的Tile图片时必须考虑周围8个坐标中的地表。为此,我们首先准备10幅Tile图片,一幅表示是100% 的草原,一幅是100% 的荒漠,其余8幅分别表示草原的占有量从1/9变化到8/9,而荒漠的占有量从8/9下降到1/9。现在假设要在某个坐标处放置一个草原地表,先对周围8个坐标中的地表进行判断,如果这8个坐标中的地表也是草原,那么该坐标处就使用100% 的草原地表;如果周围8个坐标中有的是荒漠地表,那么就计算它们的个数,最后根据这个数选择一个草原占用适当比例的Tile图片,比如8个坐标中有3个是荒漠地表, 那么就选择草原占6/9的那个Tile图片作为该坐标的图片。如果周围8个坐标中不止包含了草原和荒漠两种地表,那么我们将选择其中占用坐标数量最多的那种地表来作为判断的依据。 
    使用这种方法大大简化了地表过渡的问题,可以较好地处理普通地表之间的衔接。但同时该方法也存在着很大的局限,在处理象水这种地表的过渡问题时很难取得令人满意的效果。 
    1.5、地图数据结构的定义 
    地图数据结构的定义是斜视角游戏的地图设计中非常重要的一个部分。在斜视角游戏中每个地图坐标都涉及到许多内容,如该坐标处的地表类型、Tile图片等,所以通常使用结构体对地图中的每个坐标进行描述,而所有的地图信息存放在一个二维数组中,也就是说可以使用一个二维结构体数组来存放地图信息。在定义此结构体的内容时应该注意两个问题,一是结构体不能太大,因为在游戏中地图的范围通常都很大,有的可以达到256X256或者更多,如果每个坐标使用的结构体占用过多字节的话,整个地图将占用巨大的内存空间;另外一个应该注意的问题是:在定义每个坐标使用的结构体时应该充分考虑地图上的物体和精灵,它们和地图之间的关系非常紧密。定义得好的地图结构体可以十分方便地描述地图上的物体和精灵。 
     
    图1.4 地图数据结构的定义 
    在斜视角游戏中,因为每块Tile都是菱形的,所以整个地图看起来也就是一个大的菱形。游戏中地图坐标系一般是象图1.4中那样定义的,即将最高的那个菱形顶角处的坐标作为坐标系的原点,其地图坐标就为(0,0)。X轴增长的方向是右下方,Y轴增长的方向是左下方。 
    按照一般的思想,在地图中最小体积的精灵占一个地图坐标,大一些的占两个或更多的地图坐标。但按照这种想法,在想增大地图时中就会出现一个的矛盾。要么通过增加地图数组的大小来增加地图范围,这样必然会造成地图占用的内存迅速增加;要么通过增加每块Tile图片的大小来增加地图范围,但这样将使单个精灵占用的面积和移动时的跨度变得过大,看上去很不自然。为了解决这个矛盾,许多游戏都使用了自己的方法,我在演示程序中也因此提出了逻辑坐标系的概念。 
     
    图 1.5 逻辑坐标系和地图坐标系的关系 
    所谓逻辑坐标是专门为描述精灵的位置而提出的一个假想的坐标系统。精灵每时每刻的位置都是基于该坐标系的,它和地图坐标系相重合,但使用地图坐标系2倍的刻度单位。就是说地图坐标系中1个刻度单位对应逻辑坐标系中2个刻度单位,图1.5清楚地说明了这一点。使用逻辑坐标系只需在每个地图坐标结构体中增加很少的字节,带来的好处就是可以通过增大每个Tile图片的大小,从而扩大地图画面的面积,而且不会有每个精灵占用面积或移动跨度过大的情况,因为精灵可以停留在同一Tile上的不同位置(如果象图1.5中那样建立逻辑坐标系,精灵可以停留在同一Tile中的4个不同位置)。 
    前面已经说过,由于地图通常比较大,所以每个存放每个坐标处的内容的结构体不能占用太多的字节,但对每个坐标上内容描述得越详细,对地图、物体以及精灵的操作就会越方便。为了使每项内容占用尽可能少的空间,演示程序中使用了对内容进行压缩存储的方法。举例来说就是如果某项内容的值不会超过15,那么就只使用4位(bit)来表示它;如果不超过63,就只使用6位来表示它。这样可以去除每项内容的冗余信息,将本来需要几个字节存放的内容压缩到1个或2个字节中来。

     

     

    2.1、游戏中的物体 
    游戏中物体最明显的特征就是其在地图上位置是不会发生改变的,诸如树、房屋、巨石等都属于物体的范畴。物体的位置不会发生改变并不就是说物体是完全静态的,在许多游戏中经常可以看到树和草等物体随风摆动等情景,不过这些只是表示物体的图片在不断改变而已,物体的位置并没有改变。 
    在定义描述物体的数据结构时应该注意斜视角游戏中物体的几个特性: 
    1) 物体在地图中可能占用不只一个的地图坐标,而且这些坐标组成的可能并不是规则的矩形。处理占用不规则区域的物体是经常遇到的问题,在演示程序中采用了这样的方法:将物体按占用的坐标分为几个部分(占用几个坐标就分成几个部分),并且指定其中的一个为基准部分,然后给每个物体都分配一个数组用于记录物体中每个部分相对于基准部分的坐标偏移。当物体放到地图上后,要修改地图数组中物体占用坐标对应的数组元素内容,以便确定每个坐标上对应的物体部分,对于基准部分,在对应的地图数组元素中要设置相应的标志。 
    2) 物体每个部分对应的高度可能是不同的。在有的游戏中对于地图的描述除了使用X和Y两个坐标轴之外,还使用了一个用于表示每个地图坐标处高度的坐标轴。在这样的游戏中,物体通常也是有高度属性的,而且每个部分的高度可能不同,于是在定义物体的数据结构时还应该包含物体各部分的高度属性。而当物体放到地图上后,还应该改变物体占用的地图坐标处的高度值。 
    3) 物体是有阴影的,所以在描述物体的数据结构中不仅需要有物体本身图片的信息,还要有阴影图片的信息。 
    以上是斜视角游戏中物体的一些基本的特征。对于不同的游戏,物体还应该包含许多属性,比如:物体是否会被毁坏、物体是否有动画效果、物体是否有伤害性等等。 
    2.2、游戏中的精灵 
    与物体最大的区别就在于精灵会在地图上移动,而且精灵使用的是逻辑坐标而不是地图坐标。精灵同样有有些自己的特征,在定义描述精灵的数据结构时应该加以注意。 
    1) 精灵有可能不只占用了一个逻辑坐标,但是考虑到移动精灵时的方便性,精灵占据的通常是一个规则的矩形。这样就可以使用一个基准部分属性和两个边长属性来描述精灵占有的区域,而不用象物体中那样使用一个相对坐标数组。 
    2) 由于精灵可以移动,所以必须有各个方向上精灵运动的图片和对应的阴影图片。在制作精美的游戏中,精灵的运动都伴随着动画,这样各个方向上的动画图片和对应的阴影图片也就必不可少了。 
    3) 不同精灵可到达的区域是不同的。这是由精灵自身的属性决定的。对于可以飞的精灵,它可能可以到达地图上的任何一个地方;而在水中生活的精灵当然不能移动到陆地上,相反也是一样。精灵可到达区域的不同就决定了在移动精灵时必须对前面的地形进行判断,从而决定精灵是否可以移动。 
    4) 精灵的移动虽然是基于坐标系统的,但在进行精灵的移动处理时却不能将精灵的图片一下就移动到下一个坐标处,因为这样会使精灵图片的移动幅度过大从而出现不连贯的感觉。演示程序中使用了一个较好的方法,先求出在下一个逻辑坐标处精灵图片应该显示的位置,然后在该位置和当前精灵图片显示的位置之间使用画直线的算法来确定精灵图片的移动轨迹。在真正移动时将精灵在两个逻辑坐标间移动的过程分成多步进行,每一步都按照计算所得的直线轨迹显示精灵的图片,从而实现精灵在坐标间的平滑移动。 
    在实际的游戏中精灵的控制要比物体复杂得多,这不仅因为要根据精灵不同的状态使用不同的图片,而且因为在游戏中通常为精灵融入了思维,也就是通常所说的人工智能。因此精灵拥有更多的属性,需要对所处的环境进行更多的判断。

     

    在上面对地表、物体和精灵的叙述中都没有说明是怎么确定它们的图片在屏幕上的位置的,这是因为这要涉及到一个新的概念,就是绝对坐标系。它是为了方便地确定游戏中各种图片在屏幕上的显示位置和解决物体遮挡问题而引入的一个坐标系。下面首先结合图3.6来说明确定Tile图片在屏幕中显示位置的方法。 
     
    图3.6 绝对坐标系 
    在绝对坐标系中使用像素作为刻度单位,坐标原点就是地图坐标为(0,0)的Tile的图片的左上角,即图中的A点,X和Y坐标轴(图中没有标出) 就是穿过A点的水平直线和垂直直线,X轴的正方向是水平向右,而Y轴的正方向是垂直向下。由图中可以看出,地图横坐标(X)每增加一个单位,Tile图片的输出位置就在水平方向上增加width/2个像素,在垂直方向上增加height/2个像素;而地图纵坐标(Y)每增加一个像素,Tile图片的输出位置就在水平方向上减少width/2个像素,在垂直方向上增加height/2个像素。所以,地图坐标为(x,y)的Tile的图片在绝对坐标系中的输出位置(ax,ay)可以用下面的公式得到: 
    ax = (width / 2) * (x – y),ay = (height / 2) * (x + y) 
    如图中灰色Tile的图片在绝对坐标系中的输出位置B点的坐标为: 
    Bx = (width / 2) * (3 – 1) = width,By = (height / 2) * (3+1) = height * 2 
    为了计算出Tile图片在屏幕上的输出位置,还必须记录每个时刻屏幕区域(视口)在绝对坐标上的位置。假设当前视口的左上角的绝对坐标为(vleft, vtop),那么Tile图片在屏幕上的输出位置(px, py)就是: 
    px = ax – vleft,py = ay – vtop 
    有了Tile图片的输出位置以后,确定物体图片的输出位置也就不难了。输出物体图片时可以先计算物体基准坐标处Tile图片的输出位置,然后根据物体形状再加上一个偏移量就可以了。 
    对于精灵图片输出位置的确定,其基本思想和物体是一样的,但是应该注意,精灵使用的是逻辑坐标系,而不是地图坐标系。换句话说,精灵可能停留在同一块Tile上的不同位置上。所以应该先求出精灵基准坐标是处于哪个地图坐标中,并以次求出该地图坐标Tile图片的输出位置。然后根据精灵基准坐标处于该Tile的哪个部分加上一个偏移量,最后再根据精灵的形状加上另外一个偏移量即得到精灵图片的输出位置。

     

     

    斜视角为2D游戏带来了立体感,增加了游戏的视觉效果,但同时也为游戏的制作带来了新的困难。其中一个就是如何解决物体和精灵之间的遮挡问题。众所周知,在真实的世界中对于人的眼睛来说,前面的物体会完全或部分地遮挡住后面的物体。但是在2D游戏中,所有的物体和精灵都是使用图片来表示的,而不象3D世界中是一个个的实体,所以在2D游戏中,尤其是在斜视角游戏中,解决物体和精灵的遮挡问题是游戏制作中的一个难点。即使在许多成功的商业游戏中,在这一点上也没有做到十全十美。 
    既然在2D游戏中所有的物体和精灵都是以图片来表示的,那么物体和精灵间的遮挡问题必然涉及到图片的绘制顺序问题。所以解决遮挡问题的核心也就是确定图片的绘制顺序。首先可以将精灵分为两类,一类是在地面上移动的,另外一类是在空中飞行的。在空中的精灵,由于它们比地面的物体都高,而且就算它们重叠在一起,也不会给人不真实的感觉,所以对于它们可以不进行特别的遮挡处理,只需要在绘制完其它的物体和精灵之后再绘制它们就可以了。对于在地面上的精灵,由于每一时刻它们只能在地图的某个位置上,所以在遮挡问题上可以将它们作为物体来看待。因此,我们最终的问题归结到如何解决物体间的相互遮挡上来。 
    通过仔细观察斜视角地图的结构不难发现这样的规律,对于只占用了一个地图坐标的物体来说,使用画家算法对进行绘制就可以保证它们之间正确的遮挡关系。所谓画家算法就是指先画远的物体再画近的物体,这样近的物体必然会遮住远的物体。在斜视角游戏中可以这样确定物体的远近:物体在地图上的Y坐标越大,物体就越近,如果Y坐标值一样,那么X坐标越大,物体就越近。按通常的习惯,在二维的地图数组中使用行表示Y坐标,使用列表示X坐标,所以对于只占用一个坐标的物体来说, 可以按这样的顺序进行绘制:先以列值从小到大的顺序绘制第一行中的物体,然后以同样的顺序绘制第二行和以后各行,正如下面的程序段中的一样: 
    S_MAPITEM Map[n][n]; // n行n列的地图数组 
    int i, j; 
    for (i = 0; i < n; i++) 

    for (j=0; j < n; j++) 

    绘制 Map[i][j] 处的物体 


    对于占用了不止一个地图坐标来说,情况就远没有怎么简单了。在演示程序中解决这种物体遮挡问题时利用了物体的基准坐标和绝对坐标。先看图4.1中的三幅图片: 
     
    (a) 
     
    图4.1 物体间的遮挡 
     
    (c) 
    图4.1显示了解决树(物体1)和房屋(物体2)两个物体之间遮挡问题的过程。在演示程序中使用物体的基准坐标来判断是否该绘制某个物体,图(a)中显示了两个物体在地图上的位置和它们各自的基准坐标(灰色部分),可以看出房屋的基准坐标比树的“远”,所以当使用画家算法绘制物体时,根据前面的程序段,房屋应该比树先被绘制,于是结果就如图(b)中所示的那样,树画到了房屋的前面,这时需要对画面进行修正。修正的方法是当绘制树的时候应该判断一下它的图片是否和已经绘制的物体图片有相交的部分(图(b) 中清楚地显示了树的图片和房屋的图片有相交的部分),判断时使用的就是两个图片的绝对坐标。如果有,而且先画的物体应该遮挡后画的物体,则需要重新绘制先画的图片中相交的那一部分。经过这样的处理,就可以出现象图(c)中所示的正确结果。 
    上面的这种方法对形状比较规则的物体进行遮挡处理是非常有效的。对于更加复杂的情况,如两个物体间互相都有被对方遮住等,可以通过将一个物体分割成多个物体,从而使物体的形状变得比较规则,然后再使用上面的方法来解决遮挡问题。

     

     

    在大多数斜视角游戏中地图范围都比较大,单靠一个显示屏是无法同时显示地图的全部区域的,而且在游戏中通常只使用显示屏的一部分显示地图,剩下的部分作为和用户交互时使用。于是就有了视口的概念,视口指的就是屏幕上显示的地图区域。为了清楚地表示出视口在整个地图上的位置,换句话说就是当前屏幕上显示的地图是整个地图区域的哪个部分,在游戏中经常使用微缩地图。微缩地图是在屏幕上一个形状同整个地图相似,并且使用一些不同颜色的像素来表示地表、物体、精灵等的区域,通常在微缩地图上使用一个矩形的方框来表示当前视口在整个地图中的位置。 
     
    图5.1 微缩地图 
    图5.1是一个大小为96×96的地图的微缩地图,在此微缩每个像素代表实际地图中的一个Tile,不同的颜色分别表示地图中的草原、沙漠、水等地表区域和树、房屋等物体,而白色的矩形框表示当前视口的位置。在微缩地图中, 虽然使用一个像素表示实际地图中的一个Tile,但它们的排列是有所不同的,图5.2中说明了这一点。在微缩地图中将实际地图中交错的两排Tile使用一行像素来表示。造成这种不同的一个原因是像素不能象Tile一样。 
     
    图5.2 实际地图到微缩地图的映射方法 
    交错地排列,还有就是为了使微缩地图看起来更美观和更容易理解。为什么说更加美观和更容易理解呢?先看一下在演示程序中曾经尝试使用的另一种微缩地图的表示方法,见图5.3: 
     
    5.3 实际地图到微缩地图的映射方法(已经被淘汰) 
    可以想象,使用这种像素排列方式形成的微缩地图是一个宽明显小于高的菱形,明显不如图5.1中那样能够让人接受。所以显示程序中使用了图5.2中那样的像素排列方式,这也是为什么图5.1中微缩地图的宽是191个像素,而高是96个像素。 
    要想在微缩地图中表示出视口的位置,就必须要有能够求出实际地图中每个Tile对应于微缩地图中哪个像素的方法。为了描述的方便,在微缩地图中建立了图5.1中所示的坐标系,假设地图坐标(0,0)在微缩地图上对应像素的坐标为(a,0),那么根据图5.2可以推算出地图坐标(mx,my)在微缩地图上对应的像素坐标(x,y)为: 
    x = a + mx - my; y = (mx+my) / 2 
    应该注意的是mx和my都是整数,对于整数运算,(mx+my)/2并不等于mx/2+my/2。a的值是很好求的,对于96×96的地图来说,它就是96。有了这个算法,就可以在微缩地图上确定当前视口左上角的位置了,那么在微缩地图的视口宽和高分别是多少呢?为了说明这个问题,借助一下图4.1(a),假设它表示的就是当前的视口,使用图5.2中像素的对应方法,可以得出该视口在微缩地图上的宽为7个像素,而高为6个像素。好象宽和高的比例发生了变化,这是因为实际地图中的两排Tile变成了微缩地图中的行像素。现在,视口左上角在微缩地图上的坐标以及视口在微缩地图上的宽和高都已经知道,就可以在微缩地图上绘制代表它的矩形框了。 
    关于微缩地图还需补充一点的是:究竟是应该使用地表的代表色还是使用物体和精灵的代表色来表示微缩地图上对应像素的颜色呢? 

    展开全文
  • SCNView切换相机视角

    千次阅读 2017-01-04 17:03:08
    然后在代码中打印出position,由于我这边美工给的模型坐标系跟xcode默认的坐标系不一样,所以拖拽的position跟代码打印出来的是不同的,所以我这里需要先打印下你的相机位置,再给它设置为打印所得的position。...
  • 欢迎来到theFlyer的博客—希望你有不一样的感悟 前言:这是一篇要讲的论文,以下内容是基于个人理解写的,从简单的NMF讲到论文的多视角方法,由于之前做了PPT所以以下图片可能比较多。 论文名称 Diverse ...
  • 小白视角来看传说中的卷积神经网络

    千次阅读 多人点赞 2020-05-14 17:10:56
    从小白的视角来看卷积神经网络 笔记比较详细,但肯定也有很多地方写的清楚或者正确,还望指正 如果你和我一样是小白,希望对你有所帮助
  • Android上使用ASIFT实现对视角变化更鲁棒的特征匹配

    万次阅读 热门讨论 2010-12-24 19:25:00
    用NDK封装ASIFT算法,从而达到在Android上使用ASIFT实现对视角变化更鲁棒的特征匹配
  • 用平面棋盘做的标定板,查找棋盘中的角点,然后使用opencv的findFundamentalMat计算两个视角的基础矩阵时,第三个参数用7点法或八点法和ransac算法时,求出的矩阵结果不同,而且连光心位置都不一样了,画极线的时候...
  • 从输入/输出的视角看TCP/IP(终端,shell以及X Window)

    千次阅读 多人点赞 2019-05-10 22:22:26
    TCP/IP是迄今为止IT领域最伟大的发明,没有之一。 是时候总结一篇散文了。 第二个TCP/IP协议栈构建好的当时,这便征服的起点。...有人会怼,Windows的远程桌面一样吗?嗯,是的,看起来差不多,但是那是 带着...
  • 「HyperAI超神经」是一个科技实验媒体,我们力图通过文字,带给大家一个看待科技的独特视角。 我们的愿景是推动中文领域对机器智能的认知与普及,探讨机器智能的对社会的影响。 如果你想了解更多,可以通过我们往期...
  • 全景图片拼接

    千次阅读 2015-01-05 17:41:35
    最近在做老师布的一个作业,原来是要做全景视频合成,可是做出来发现实时性根本达到,改成全景图片合成吧。废话多说啦,说说原理。 原理: 1 直方图均衡化对图片三个信道进行归一化处理。 2 柱面投影 3 图片...
  • 从 iOS 视角解密 React Native 中的线程

    千次阅读 2017-01-17 11:30:35
    1 从 iOS 视角解密 React Native 中的线程 iOS React-Native 线程 GCD 组件 阅读3296
  • 基于多视角照片的3D人脸重建

    万次阅读 2015-03-10 21:48:35
    5.3.2 基于多视角照片的3D人脸重建 多视角三维重建的技术原理请详见第6章6.3节“立体视觉重建:将照片转成3D数字模型”,本节主要介绍如何具体地操作和应用。Autodesk(欧特克)公司发布了一个建模软件 ...
  • 如何制作VR所需要的全景图片或video

    万次阅读 2016-07-30 21:21:57
    这里就介绍第一种方法,主要来说一说如何用鱼眼相机或者全景摄像机来获取我们VR所要使用到的可以360度的图片和video 在了解前,我们先要对拍摄技巧,和所用到的一些摄像技巧进行一些探究。 进入正题带着我们的好奇...
  • 一个可以自由在XZ轴平面移动,向任意方向调整视角的3D房间的建立详解
  • 上面我就是从在线帮助中截取几张图片而已,好在在线帮助也都是中文化的了,在一个爽心的下午,品着拿铁,信手翻来也不失乐趣。   按照一开始的规划,第三篇要写的是 GIS 的连通性分析,也就是回答 What...
  • 与科学技术的任何其他发展一样,计算机和互联网的发展也并非没有危险。 这是因为互联网网络空间是传播信息最简单和最快的媒体之一,它有可能被道德的人滥用。 网络空间由于其内容、信息、帖子、图片、观点的多样...
  • ······················· 从第三方下载回来的库【只用改】 ├─ /favicon.ico ················ 站点图标 └─ /index.html ················· 入口...
  • 本文图片素材来自ue4官网 这是个用ue4引擎结合编辑器、蓝图和C++编程实现的简单第三人称视角游戏。涉及到场景编辑、材质编辑、脚本编程、UI等内容。 游戏概览 游戏主要是控制角色跑动捡取电池充电,充电后移动...
  • Flash开发的斜视角下的地图编辑器

    千次阅读 2009-02-15 22:16:00
    开发斜视角游戏,地图编辑器其实还是很重要的,很多的显示方面的逻辑都会用到。今天跟大家分享一下我们做的地图编辑器。关于开发中的一些比较重要的技术要点:物体层级判断和物体的精确选取,我之间发过帖子进行过...
  • Spectator view——Hololens第三人称视角技术的详细实现过程距离微软发布首个受线缆限制的全息计算机设备Hololens已经快过去三个年头,而随着新技术的不断出现,MR这一曾经“万众瞩目”的技术也逐渐退出了大众们的...
  • base64-图片传输

    万次阅读 多人点赞 2018-09-09 23:42:44
    大家看标题就知道,但是我也只是作为一个新人的视角去认识这个base64,大概了解了一下,没有太深入,因为前段有很好的base64工具,java也有BASE64Decoder包,所以我就以一个如何使用的角度来总结一下。 说来惭愧,...
  • 随后,希望互联网上的矢量图片标准被这些巨头垄断的其他公司在W3C内成立了一个专门小组SVG Working Group,在借鉴了前两种提案后,提出了SVG规范,随后被接纳为相当于标准的W3C推荐(W3CRecommendation)。...
  • Android超炫图片浏览器代码

    万次阅读 2011-08-05 14:41:50
    使用过Android自带的gallery组件的人都知道,gallery实现的效果就是拖动浏览一组图片,相比iphone里也是用于拖动浏览图片的coverflow,显然逊色不少。实际上,可以通过扩展gallery,通过伪3D变换可以基本实现cover...
  • 基于(图像)序列视角,我们的方法受帧的排列的影响,并且可以自然地整合来自不同视频的帧,这些视频已经在不同的场景下被完成,例如不同的视角,不同的衣服/携带条件。 Experiments show that under normal ...
  • 但在正交摄像机中,物体的大小就和摄像机的距离息息相关了,就像是真实的人眼看世界一样,近大远小.那该如何把我这个距离呢? 透视摄像机的属性 距离计算 相机视角 = 60度,那么角α =60/2 = 30度,所以tanα ...
  • [转] https://www.leiphone.com/news/201804/1XOG6onAGs3sdwDq.html来自华盛顿大学艾伦人工...这种表示学习方法与传统的图片训练任务的不同之处在于,它的模型训练是从特定视角出发,所以这是一种全新的CV任务。在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,721
精华内容 7,488
关键字:

一样的图片不一样的视角