三种前端实现VR全景看房的方案!说不定哪天就用得上!

您所在的位置:网站首页 河源vr全景 三种前端实现VR全景看房的方案!说不定哪天就用得上!

三种前端实现VR全景看房的方案!说不定哪天就用得上!

2023-09-17 23:59| 来源: 网络整理| 查看: 265

前言

事情是这样的,前几天我接到一个外包工头的新需求,某品牌要搭建一个在线VR展厅,用户可以在手机上通过陀螺仪或者拖动来360度全景参观展厅,这个VR展厅里会有一些信息点,点击之后可以呈现更多信息(视频,图文等)...

image.png

我第一反应是用3D引擎,因为我不久前刚用three.js做过一个BMW的在线展厅,基本把three.js摸熟了。

2021-06-03 11_01_41.gif

会另写一篇文章教大家用threejs做这个[BMW在线DIY],感兴趣的小伙伴请关注我吧~

方案一:WebGL3D引擎

使用3D引擎先搭一个基本的3D场景,下面的演示使用three.js,同类的3D引擎我还调研过babylon.js,playcanvas,使用都差不太多,学会一个基本都通的

var scene, camera, renderer; function initThree(){     //场景     scene = new THREE.Scene();     //镜头     camera = new THREE.PerspectiveCamera(90, document.body.clientWidth / document.body.clientHeight, 0.1, 100);     camera.position.set(0, 0, 0.01);     //渲染器     renderer = new THREE.WebGLRenderer();     renderer.setSize(document.body.clientWidth, document.body.clientHeight);     document.getElementById("container").appendChild(renderer.domElement);     //镜头控制器     var controls = new THREE.OrbitControls(camera, renderer.domElement);          //一会儿在这里添加3D物体     loop(); } //帧同步重绘 function loop() {     requestAnimationFrame(loop);     renderer.render(scene, camera); } window.onload = initThree;

现在我们能看到一个黑乎乎的世界,因为现在scene里什么都没有,接着我们要把三维物体放进去了,使用3D引擎的实现方式无非都是以下几种

使用立方体(box)实现

这种方式最容易理解,我们在一个房间里,看向天花板,地面,正面,左右两面,背面共计六面。我们把所有六个视角拍成照片就得到下面六张图

image.png

现在我们直接使用立方体(box)搭出这样一个房间

var materials = []; //根据左右上下前后的顺序构建六个面的材质集 var texture_left = new THREE.TextureLoader().load( './images/scene_left.jpeg' ); materials.push( new THREE.MeshBasicMaterial( { map: texture_left} ) ); var texture_right = new THREE.TextureLoader().load( './images/scene_right.jpeg' ); materials.push( new THREE.MeshBasicMaterial( { map: texture_right} ) ); var texture_top = new THREE.TextureLoader().load( './images/scene_top.jpeg' ); materials.push( new THREE.MeshBasicMaterial( { map: texture_top} ) ); var texture_bottom = new THREE.TextureLoader().load( './images/scene_bottom.jpeg' ); materials.push( new THREE.MeshBasicMaterial( { map: texture_bottom} ) ); var texture_front = new THREE.TextureLoader().load( './images/scene_front.jpeg' ); materials.push( new THREE.MeshBasicMaterial( { map: texture_front} ) ); var texture_back = new THREE.TextureLoader().load( './images/scene_back.jpeg' ); materials.push( new THREE.MeshBasicMaterial( { map: texture_back} ) ); var box = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), materials ); scene.add(box); 2021-06-14 19_51_17.gif

好,现在我们把镜头camera(也就是人的视角),放到box内,并且让所有贴图向内翻转后,VR全景就实现了。

box.geometry.scale( 1, 1, -1 );

现在我们进入了这个盒子!!

2021-06-14 19_41_37.gif

threejs官方立方体全景示例

使用球体(sphere)实现

我们将房间360度球形范围内所有的光捕捉到一个图片上,再将这张图片展开为矩形,就能得到这样一张全景图片

image.png var sphereGeometry = new THREE.SphereGeometry(/*半径*/1, /*垂直节点数量*/50, /*水平节点数量*/50);//节点数量越大,需要计算的三角形就越多,影响性能 var sphere = new THREE.Mesh(sphereGeometry); sphere.material.wireframe  = true;//用线框模式大家可以看得清楚是个球体而不是圆形 scene.add(sphere); image.png

现在我们把这个全景图片贴到这个球体上

var texture = new THREE.TextureLoader().load('./images/scene.jpeg'); var sphereMaterial = new THREE.MeshBasicMaterial({map: texture}); var sphere = new THREE.Mesh(sphereGeometry,sphereMaterial); // sphere.material.wireframe  = true; 2021-06-14 14_54_38.gif

和之前一样,我们把镜头camera(也就是人的视角),放到球体内,并且让所有贴图向内翻转后,VR全景就实现了

现在我们进入了这个球体!!

var sphereGeometry = new THREE.SphereGeometry(/*半径*/1, 50, 50); sphereGeometry.scale(1, 1, -1); 2021-06-14 15_15_28.gif

threejs官方球体全景示例

添加信息点

在VR全景中,我们需要放置一些信息点,用户点击之后做一些动作。

现在我们建立这样一个点的数组

var hotPoints=[     {         position:{             x:0,             y:0,             z:-0.2         },         detail:{             "title":"信息点1"         }     },     {         position:{             x:-0.2,             y:-0.05,             z:0.2         },         detail:{             "title":"信息点2"         }     } ];

遍历这个数组,并将信息点的指示图添加到3D场景中

var pointTexture = new THREE.TextureLoader().load('images/hot.png'); var material = new THREE.SpriteMaterial( { map: pointTexture} ); for(var i=0;i0){         alert("点击了热点"+intersects[0].object.detail.title);     } }); 方案二:CSS3D

threejs等3d引擎太强大了,这些引擎的代码量都有大几百K,在今天的网速下显得无所谓,但在几年前我接到需求时仍然是重要的考量因素。既然我们只用到3D引擎的一点点功能,那么能否找到一个更加轻量的3D引擎呢。

有!css3d-engine,这个3d引擎只有14kb,并且在多个大牌商业项目中应用

淘宝造物节 https://shrek.imdevsh.com/show/zwj/

adidas绝不凋谢 https://shrek.imdevsh.com/show/drose/

adidas胜势全开 https://shrek.imdevsh.com/show/bbcny/

adidas绝不跟随 https://shrek.imdevsh.com/show/crazylight/

使用skybox实现 window.onload=initCSS3D; function initCSS3D(){     var s = new C3D.Stage();     s.size(window.innerWidth, window.innerHeight).update();     document.getElementById('container').appendChild(s.el);     var box = new C3D.Skybox();     box.size(954).position(0, 0, 0).material({         front: {image: "images/scene_front.jpeg"},         back: {image: "images/scene_back.jpeg"},         left: {image: "images/scene_right.jpeg"},         right: {image: "images/scene_left.jpeg"},         up: {image: "images/scene_top.jpeg"},         down: {image: "images/scene_bottom.jpeg"},     }).update();     s.addChild(box);     function loop() {         angleX += (curMouseX - lastMouseX + lastAngleX - angleX) * 0.3;         angleY += (curMouseY - lastMouseY + lastAngleY - angleY) * 0.3;         s.camera.rotation(angleY, -angleX, 0).updateT();         requestAnimationFrame(loop);     }     loop();     var lastMouseX = 0;     var lastMouseY = 0;     var curMouseX = 0;     var curMouseY = 0;     var lastAngleX = 0;     var lastAngleY = 0;     var angleX = 0;     var angleY = 0;     document.addEventListener("mousedown", mouseDownHandler);     document.addEventListener("mouseup", mouseUpHandler);     function mouseDownHandler(evt) {         lastMouseX = curMouseX = evt.pageX;         lastMouseY = curMouseY = evt.pageY;         lastAngleX = angleX;         lastAngleY = angleY;         document.addEventListener("mousemove", mouseMoveHandler);     }     function mouseMoveHandler(evt) {         curMouseX = evt.pageX;         curMouseY = evt.pageY;     }     function mouseUpHandler(evt) {         curMouseX = evt.pageX;         curMouseY = evt.pageY;         document.removeEventListener("mousemove", mouseMoveHandler);     } }

方案二的好处除了库很小以外,还是div+css来搭建三维场景的。但这个库的作者几乎不维护,遇到问题必须得自己想办法解决,比如使用在电脑上会看到明显的面片边缘

image.png

但是在手机上浏览的话表现还是相当完美的

2021-06-14 22_20_26.gif 添加信息点

我们继续为它添加可交互的信息点

var hotPoints=[     {         position:{             x:0,             y:0,             z:-476         },         detail:{             "title":"信息点1"         }     },     {         position:{             x:0,             y:0,             z:476         },         detail:{             "title":"信息点2"         }     } ]; function initPoints(){     var poiObjects = [];     for(var i=0;i{     var pois=pano.getPointHotspotIds();     var hotScale = 0.2;     for(var i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3