threejs实现简单全景看房demo
各位大家好😊,最近一直在学习 threejs ,在学习过程中不断进步,在将来我会不断完善我的 threejs 案例库,希望能在学习路上帮到大家🌹
接下来为各位介绍的是一个全景看房的demo,我们先上地址:
- 源码地址:https://github.com/ljnMeow/360-house-viewing.git
- 预览地址:https://ljnmeow.github.io/360-house-viewing/dist
- 全景图切割工具:https://matheowis.github.io/HDRI-to-CubeMap/
前言
threejs 是 javascript 编写的一个 WebGL 第三方库。在 threejs 中,我们通过 Scene(场景) 、 Camera(相机) 和 Renderer(渲染器) 来实现一个3d的场景,然后往里面添加各种光源、物体等等,形成一个3d世界。
threejs支持程度
因为 threejs 是基于 webgl 写的,所以我们主要看设备是否支持 webgl 。据我所知目前主流最新版本的设备、浏览器都支持 webgl,但如果客服要在一些早期的设备上跑,例如某些超大屏大屏监控系统,跑这个的设备可能是早期的 IE 并且无法升级。我们还是需要权衡下早期 IE 和 安卓、苹果设备是否支持 webgl, 详情可见下图:
基本介绍
要实现3d图形的展示,大致是以下思路:
- 创建三维场景(Scene)
- 选择视觉点并确认视觉位置角度(Camera)
- 添加物体供观察
- 渲染场景(Renderer)
Scene
场景是我们所有物体的容器,通俗来讲就相当于我们的世界
Camera
相机是我们这个世界的观察者,使用右手坐标系定位
threejs 常用的相机有两种,分别是 正交投影相机(OrthographicCamera) 和 透视投影相机(PerspectiveCamera) ,下面是我对这两种方式的理解,错了请各位大佬指点我一下🤞
正交投影相机(OrthographicCamera)
正交投影是一种相对简单的投影模式,我们可以把该模式看作看作一个长方形矩形,总共有6个面。该模式的特点是无论出于矩形中的哪个位置,其投影的大小都是一样的,通俗理解就是该模式跟常生活中的视觉效果不一样。我们平时看物体是远小近大,而该模式下展示的物体无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。通过下面图片能清楚看到,相机视觉中的物体投放到进平面,然后近平面中的物体渲染到远平面也就是屏幕中,并且无论投放在哪一面,物体的大小都不变。
透视投影相机(PerspectiveCamera)
透视投影的视觉效果呈现一个锥形,该模式就是我们现实世界中的视觉体现。该模式的特点是物体远小近大。
相机效果体验地址在官方demo中有:https://threejs.org/examples/#webgl_camera
Renderer
渲染器渲染我们精心制作的场景
进入正题
根据我的了解目前常用于实现全景看房效果的有两种,分别是 天空盒(skyBox) 和 全景图片贴图 ,我这个demo使用的是后者。
实现方式
skyBox
skyBox 方法是最容易理解的,在我们身处的场景内,无非就是6个面,上下、前后、左右。将这6个面的视觉处理成图片就得到6张不同方向视觉的图片。
我们将6个视觉的图片贴到立方体的6个面,可以得到一个房间。
1 | initContent() { |
将视觉移到立方体中心,并让贴图内翻转一下,就能实现全景看房
1 | this.box.geometry.scale(10, 10, -10); |
全景图贴图
全景图贴图这种方式我认为是简单而且效果最好的一种。写之前需要一张全景图片,这个用单反的全景模式就能拍一张
threejs 添加一个球体。并把全景图作为贴图贴到球体上,得到的效果如下:
1 | initContent() { |
同样,把视觉放球内,贴图反转。
1 | sphereGeometry.scale(16, 16, -16); |
添加标签
我们现在已经实现全景看房了,接下来给一些物体添加说明标签,我这边的标签分两种,一种点击能够进入下一个房间,一种是弹出信息框。先看效果:
下面看看我的数据结构
1 | dataList: [ |
往场景中添加标签,得到如下效果。
1 | addTipsSprite(index = 0) { |
接下来实现鼠标移入,内容弹出效果
1 | // html |
1 | // data |
1 | // method |
1 | // mounted |
最终得到效果:
场景切换
全景看房总不能一直看一个房间,所以我们还需要实现点击切换场景功能。直接codeing…
1 | changeContentAndtips(index) { |
最终得到完整效果如下图:
总结
在这个demo中有一些细节问题我处理的不是很好,例如加载时因为贴图加载慢黑屏(这是因为贴图太大,优化时可加入等待动画),还有就是加载顺序没处理好,场景贴图还没加载完标签已经进来了。
在不断学习 threejs 的过程中,感觉还是挺有趣,看着别人炫酷的3D效果和智慧城市感觉好强,也感到自己的不足。趁着这段时间公司有项目需要用 threejs 能够光明正大摸鱼学习,努力冲啊💪
最后希望这篇文章能帮到各位❤今天是2021最后一天,祝各位大佬今天摸鱼,明年年年有余😁