需求:
1、全景图展示
2、全景图切换的时候做淡进淡出效果
需求讲解:
如果只是做单独的全景图切换、可以不用离屏渲染效果、因全景图内还有部分功能点、介绍点等
如果单个场景进行淡进淡出的话、直接调整该场景模型的透明度就可以了、但这里涉及到了多层模型的问题、会存在切换黑屏、批量循环的问题(循环用多了总是不好的)
实际实现方式:
1、材料:
两个场景(Scene)、
两个相机(透视相机PerspectiveCamera、
正交相机OrthographicCamera)、
一个控制器(OrbitControls)、
两个渲染器(WebGLRenderer、WebGLRenderTarget)、
动画执行插件(Tween) // 一个数值变换的库、自行百度
2、步骤
一、创建一个正常的场景使用正交相机进行浏览
二、创建一个缓存场景 WebGLRenderTarget (之后的所有场景更新都是在这个缓存场景内进行的)
三、在展示场景内增加一个物体、将缓存场景加载展示( buffer_target.texture 缓存场景可以直接使用texture参数进行赋值)
四、场景循环渲染(两个渲染器都要更新、单独更新某一个都是不行的、还有就是注意渲染顺序 必须先渲染缓存场景)
五、 新增场景 并切换到新的场景(这里要更新的参数有:控制器控制的场景更换、主场景的两个物体位置、旧物体的透明度、以及旧场景的清除工作)
记得要想更改看到的内容的话、一定是要更改缓存场景的数据。
还有就是场景切换记得要做限制。否则切换的时候多次创建场景的话、就GG了 哈哈 !!
这个就是我个人的用法、其实完全可以用两个场景重复使用的方式、这样的话就不怕同时创建多个场景的问题、只是我这里用不到 所有就么有研究、有兴趣的可以自己尝试一下。
反正也不知道是不是正统的方式、我这样是可以实现、或许你有更简单的方式也欢迎告知、谢谢 !!
完成!!
创建展示场景:
init() { // 主场景: 离屏渲染 this.scene = new THREE.Scene(); // this.scene.background = new THREE.Color('red') this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(window.innerWidth, window.innerHeight); document .getElementById("container") .appendChild(this.renderer.domElement); // 主场景相机 var aspect = this.width / this.height; var halfWidth = window.innerWidth / 2; var halfHeight = window.innerHeight / 2; this.camera = new THREE.OrthographicCamera( -halfWidth, halfWidth, halfHeight, -halfHeight, -1, 10000 ); this.camera.lookAt(0, 0, 0); //看向位置 this.camera.position.set(-1, 0, -1); this.scene.add(this.camera); this.newscene(); },
创建缓存场景(个人是将新建场景和更换场景的函数复用的、场景不合适你也可以写两个函数进行处理):
newscene(event) { // 新建场景 var nowscene = this.scene.children[1]; (this.width = document.documentElement.clientWidth), (this.height = document.documentElement.clientHeight); console.log("更新场景", this.width, this.height); var new_scene = new THREE.Scene(); var new_target = new THREE.WebGLRenderTarget(); // 相机设定 new_target.setSize(this.width, this.height); var new_camera = new THREE.PerspectiveCamera( 75, this.width / this.height, 1, 1000 ); new_camera.lookAt(0, 0, 0); //看向位置 if (nowscene) { var nowdata = this.buffer_camera.position; //保留当前相机位置、 new_camera.position.set(nowdata.x, nowdata.y, nowdata.z); } else { // 首次加载 new_camera.position.set(-0.1, 0, -0.1); } new_scene.add(new_camera); this.assignment(new_scene, new_target, new_camera); //更新操作场景参数 this.renderer.setSize(this.width, this.height); // 创建场景贴图 var skyGeometry = new THREE.BoxGeometry(100, 100, 100); var skyMaterial = new THREE.MeshFaceMaterial( this.lodingsex(this.NowModel.ivtimg) ); var skyBox = new THREE.Mesh(skyGeometry, skyMaterial); //创建一个完整的天空盒,填入几何模型和材质的参数 skyBox.name = "img_model"; skyBox.modeltype = 0; skyBox.scale.set(-1, 1, 1); new_scene.add(skyBox); //在场景中加入天空盒 this.Addspot(this.NowModel.spot); // 更新场景展示模型 var geometry = new THREE.PlaneGeometry(this.width, this.height, 10); var material = new THREE.MeshBasicMaterial({ // color: 0xffff00, side: THREE.DoubleSide, map: this.buffer_target.texture, }); var plane1 = new THREE.Mesh(geometry, material); plane1.name = this.NowModel.name; console.log(plane1); if (nowscene) { // 首次加载不执行加载动画 // 执行淡进淡出动画 console.log( "场景:", this.scene, "模型:", plane1, "相机:", this.camera ); plane1.position.set(-1, 0, -1); } else { plane1.position.set(0, 0, 0); } this.scene.add(plane1); },
更新控制参数:
assignment(scene, target, camera) { // 控制器与场景信息更新 this.buffer_scene = scene; this.buffer_target = target; this.buffer_camera = camera; this.orbitControls = new OrbitControls( this.buffer_camera, this.renderer.domElement ); this.orbitControls.enableDamping = true; this.orbitControls.enableZoom = false; this.orbitControls.dampingFactor = 0.05; // this.orbitControls.update(); },
渲染器更新(记得加到主动画函数里面):
render() { // 渲染器 this.renderer.setRenderTarget(this.buffer_target); this.renderer.render(this.buffer_scene, this.buffer_camera); this.renderer.setRenderTarget(null); this.renderer.render(this.scene, this.camera); },
淡进淡出动画(这是之前说的模型位置、透明度调整动画):
animateOpacity(event1, event2) { // 淡进淡出动画 console.log(event1, event2) event2.position.set(-1, 0, -1); event1.material.transparent = true; // 允许透明度设定 event1.position.set(0, 0, 0); var tween = new TWEEN.Tween({ o: 1, x: -1, y: 0, z: -1, x1: 0, y1: 0, z1: 0, }); let self = this; tween.to({ o: 0, x: 0, y: 0, z: 0, x1: -1, y1: 0, z1: -1 }, 1000); tween.onUpdate(function (obj) { // 更新场景透明度、调整场景2的展示位置 event1.material.opacity = this.o; // event1.position.set(this.x1,this.y1,this.z1); event2.position.set(this.x, this.y, this.z); }); tween.onComplete(function () { // 场景清空并删除载入场景模型 event1.geometry.dispose(); event1.material.dispose(); self.scene.remove(event1); self.animatetype = true; // 开启可进入动画入口 }); tween.easing(TWEEN.Easing.Cubic.InOut); tween.start(); },