Web全景图的原理及实现

全景图的基本原理

全景图是一种广角图。通过全景播放器可以让观看者身临其境地进入到全景图所记录的场景中去。比如像是这个。这种看起来很高大上的效果其实背后的原理并不复杂。

通常标准的全景图是一张2:1的图像,其背后的实质就是等距圆柱投影。等距圆柱投影是一种将球体上的各个点投影到圆柱体的侧面上的一种投影方式,投影完之后再将它展开就是一张2:1的长方形的图像。比较常见的就是应用在地图上的投影。

Web全景图的原理及实现

而在对全景图进行展示之前就需要得到一张这样的图像,这种图像可以自己用普通相机拍摄再自己合成,也可以直接使用专门的全景相机进行拍摄。全景照片的拍摄在网上有比较多的教程,由于这不是摄影分享就不详细的去说了:P。

在得到了全景图之后,就是要怎么去展示的问题了。接下来就要说说全景展示的原理。全景展示其实是等距圆柱投影的逆过程,我们要做的就是将我们得到的全景图,贴图到一个球体上,熟悉webgl的,可以用它画一个球体,然后将全景图作为材质贴到这个球体上进行渲染。由于使用webgl来进行编程的话,需要自己进行比较多的3d运算,所以也可以选择使用api更加友好的3D库,如THREE.JS来编程。比如下面的这张全景图,在球面上进行贴图。

Web全景图的原理及实现
Web全景图的原理及实现

这时我们看到的还跟预想的全景不一样,那是因为我们在球的外面,当我们在球的里面时,看到的就是跟一开始的示例一样的效果了。像是下面的这个示意图这样。

Web全景图的原理及实现

用threejs进行编程的话,关键的代码如下:

//新建一个球体var geometry = new THREE.SphereGeometry( 500, 60, 40 );//沿x轴进行-1的scale,让球体的面朝内(因为我们将从球内进行观看)。geometry.scale( - 1, 1, 1 );//载入一张全景图生成threejs中可以使用的材质var material = new THREE.MeshBasicMaterial( {    map: new THREE.TextureLoader().load( 'panoPic.jpg' )} );//将几何体和材质进行结合。mesh = new THREE.Mesh( geometry, material );

兼容性

虽然使用webgl可以很容易的就生成一个全景的场景,但是在web里,兼容性似乎是个挥之不去的话题。主要是由于webgl不支持Android5.0以下的机器,所以,用webgl来实现将会将很多用户排除在外。所以只能寻求更好的解决方案。首先想到的就是css 3D transform 和 2D canvas画布。在threejs里支持在2D的canvas里进行绘制,本是一个比较好的方案,但是经过测试之后,发现2d画布来绘制3d的场景,性能上太吃力。所以,也被排除。剩下的就是css变换了。但是,要怎么用css来画一个一个球体呢?答案显然是不行的。虽然css不能绘制一个球体,但是css通过3D变换来绘制立方体还是简单一些的。那么用立方体可不可以实现一样的效果呢?

球体到立方体

根据全景图的原理,我们是把视角放在球的中心,通过从球心观看球面上正式场景在球面上的映像从而产生一种空间中全方位的视觉体验,同理,对于立方体,应该也可以使用相同的方式来实现。而我们要做,就是把球面上的像素点映射到立方体上。

Web全景图的原理及实现

说了基本的原理,接下来就是进行数学建模了。首先我们建立一个球坐标系,坐标系描述的变量分别为半径r,竖直方向上的夹角θ,水平方向上的夹角ø,对于球体,我们可以假定

r=10 < θ < π -π/4 < ø < 7π/4

这样我们就可以得到球面上的各个点在直角坐标系中的x,y,z

x= r sin θ cos øy= r sin θ sin øz= r cos θ

对于球面到立方体上的投影,我们需要的是角度θ和ø相同时,延长球的半径r直到和立方体的面相交,假设这个长度是R,由于我们设了半径r是1所以球面上的点为 (sin θ cos ø, sin θ sin ø, cos θ) 对应的立方体上的点是(Rsin θ cos ø, Rsin θ sin ø, Rcos θ)

如果我们要求x=1这个平面上的点,则

1=Rsin θ cos ø

则可以求出来

R= 1/(sin θ cos ø)

所以在x平面上映射的点就是

(1, tan ø, cot θ / cos ø)

在立方体另外的五个平面上的投影也可以类似地得出。通过上述方法转换一张全景图,可以得到以下结果。

Web全景图的原理及实现

离我们想要的效果还有一些差距,图中似乎多了一些黑色的线。导致这种现象的原因是,由于我们的处理是以像素为单位来进行处理的,通过遍历球面图上的每个像素然后投影到立方体上的面来实现。经过这种方式进行投射之后,立方体的面上就会有一些像素被重复设置,而一些地方的像素就会缺失,比如图中的黑色部分(由于底色的黑色的)。为了解决这个问题,我们可以通过逆向的方法来解决,也就是遍历立方体上面上的每个点,求得映射到球面上的位置,然后获取球面上最接近的位置的像素。
Web全景图的原理及实现
得到了立方体上需要的图之后,就可以用css 3D变换来实现全景图了。

展示更多信息

单单地进行全景观看可能还不能满足我们的需求,也许我们还需要展示更多的信息,而这些信息可能是跟全景中的内容相关的,比如给全景中的物品打标,给全景中的内容添加评论,像是下图这样
Web全景图的原理及实现
对于这个实现的关键在于,屏幕2D坐标和空间3D坐标之间的相互转换。第一步需要实现的是记录,当用户点击屏幕,要根据点击的位置来计算出和空间中的立方体相交的点并记下这个点的位置信息。一些3d库当中会有一些api来帮助完成这项工作。而在THREEJS中使用的是Raycaster,Raycaster可以生成一条直线,然后可以很方便地得到三维空间中,和这条直线相交的物体和点。由于THREEJS中是以绘制的中心作为原点,而鼠标的点击位置是以左上角为原点,所以需要进行一下转换。

//将鼠标点击事件中的位置信息,转换到位置中心  var mouse = new THREE.Vector2(    ( ev.clientX / _this.wrapper.width() ) * 2 - 1,    -( ev.clientY / _this.wrapper.height() ) * 2 + 1  )

然后就可以初始化一个Raycaster获得需要的内容了

//创建一个Raycaster实例  var raycaster = new THREE.Raycaster()//根据点击的位置,从镜头开始初始化一和镜头的屏幕垂直的直线  raycaster.setFromCamera(mouse, _this.camera)//获得和直线相交的物体  var intersects = raycaster.intersectObjects(_this.scene.children)

这样就在空间中记录下了一个目标位置。

有了三维中的位置之后,如果我们想要展示这个位置相关信息,比如打一个标签,就是需要将空间中的位置还原到屏幕的二维坐标上,然后用传统的css方法来进行展示就可以了。

//根据上一步中记录的位置生成一个向量var vector  = new THREE.Vector3(pos.x, pos.y, pos.z)//将这个向量映射到镜头的平面上vector.project(camera)//将位置信息还原成以左上角为原点的位置信息var screenPos = {  left: Math.round((   vector.x + 1 ) * wrapper.width() / 2),  top: Math.round(( -vector.y + 1 ) * wrapper.height() / 2)

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请添加站长微信举报,一经查实,本站将立刻删除。

如若转载,请注明出处:http://www.ibjoo.com/298.html

(0)
市场圈市场圈普通用户
上一篇 2020年5月5日
下一篇 2020年5月5日

相关推荐

  • 装修设计360全景效果视频怎么做?需要用什么软件?

    装修设计3D全景效果图的出现颠覆了传统装修行业的营销服务模式,成为家装行业炙手可热的营销利器。但随着科技及移动互联网的发展,装修设计360全景效果视频成为装修行业新的追求,动态视频的效果/价值是否比静态图片的效果更好呢?那么,装修设计360全景效果视频怎么做?需要用什么软件? 装修设计360全景效果视频怎么做? 其实,装修设计360全景效果视频的拍摄方法和过…

    2020年4月23日
    39100
  • 全景看车怎么做的?

      汽车三维全景展示技术的特点:  1、直接在网络上看多个汽车的全景内饰与汽车外观,方便客户了解更多汽车相关信息,更好对比与筛选;  2、4S店通过三维全景技术真实在线地展示在网络平台上,可以大大提高4S店的知名度;  3、采用单反相机、鱼眼镜头、全景云台、三脚架拍摄,拍摄好的图片,然后用造景师软件合成完美高质量的汽车,真实地展现出汽车内饰,和局部细节,如图…

    VR全景教程 2020年5月5日
    19400
  • 全景漫游打开慢怎么办?

      全景漫游打开很慢一般主要有三个方面原因:  1:用户带宽传输速率低。  2:全景图文件过大。  3:第一个场景中需要加载过多的flash,图片,音频,视频等文件。  针对后面两个原因我们提供如下解决方案:  图像压缩:  通过裁剪图像的尺寸大小或降低图像质量都可以减小文件空间。  以佳能全画幅相机6D为例,该相机为2000万像素。拍摄照片最大尺寸为364…

    VR全景教程 2020年5月5日
    25400
  • 全景软件如何制作VR全景图片?

    全景软件如何制作VR全景图片? 基本上DJI的设备都满足拍摄所需,我大概列一下 1、载机:phantom I ;云台:H3-3D;相机:gopro 3+/4;图传;监视器 2、载机:phantom II ;云台:H3-3D;相机:gopro 3+/4;图传;监视器 3、一体机:phantom V+;手机 4、一体机:inspire 1;Pad/手机 基本上和…

    2020年4月23日
    19500
  • 虚拟旅游怎么实现?

      虚拟旅游,顾名思义就是利用虚拟现实技术,可以是构建好的三维立体的图片,也可以是360度的实景图片,让浏览者不用自己亲身莅临景区旅游,就能通过网络将旅游景点一览无余,给人一种身临其境的感觉。  另外我们VR云平台不仅可以实现网络空间电脑端和手机端的虚拟旅游阅览,也可以进行网民互动,点赞评论或留言,形成一种虚拟旅游的全景社区。我们既可以在VR云里上传全景图,…

    VR全景教程 2020年5月5日
    27900

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

工具推荐
公众号
公众号
分享本页
返回顶部
特别提示:欢迎收藏&使用市场工具导航,如您有任何建议或好用工具推荐,请留言告知我们。谢谢~