threejs 360房间的学习

操作流程学习

准备的基本知识

  1. 360房间的制作
  • 准备正方体,添加六个面贴图实现
    具体操作:
    六面图可以通过天空盒子工具实现 - https://matheowis.github.io/HDRI-to-CubeMap/

立方体屋子的具体操作:

const textures = cubeTextureLoader.load([
  '/textures/px.jpg',
  '/textures/nx.jpg',
  '/textures/py.jpg',
  '/textures/ny.jpg',
  '/textures/pz.jpg',
  '/textures/nz.jpg'
]);

const materials = [];
for ( let i = 0; i < 6; i ++ ) {
  materials.push( new THREE.MeshBasicMaterial( { map: textures[ i ] } ) );
}
const skyBox = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), materials );
skyBox.geometry.scale( 1, 1, - 1 );
scene.add( skyBox );
  • 准备球体,通过全景图贴图实现 - (貌似球体比正方体好,没有面与面之间的白色线接细线)
    具体操作:
    方法1: 自己拍摄,用单反的全景模式拍摄
    方法2: 用现成的,球形全景图下载网站 - https://polyhaven.com/hdris

球体360屋子的具体操作:

const geometry = new THREE.SphereGeometry(16, 256, 256);
const material = new THREE.MeshBasicMaterial({
  map: textLoader.load('全景图片地址'),
  //-- 球体内外均显示
  side: THREE.DoubleSide,
});
//-- 放大球体,让摄像机进入球体内部
geometry.scale(1, 1, -1);
const room = new THREE.Mesh(geometry, material);
  1. 房间展示的信息点,使用Sprite来实现
  • Sprite - 精灵是一个总是面朝着摄像机的平面,通常含有使用一个半透明的纹理
  1. 三维房间信息点,与鼠标实现交互
  • 通过光线投射Raycaster,这个类用于进行raycasting(光线投射)- 光线投射用于进行鼠标拾取
    代码片段:
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector2();
mouse.x = (e.clientX / element.clientWidth) * 2 - 1;
mouse.y = -(e.clientY / element.clientHeight) * 2 + 1;
raycaster.setFromCamera(mouse, this.camera);
//-- 鼠标与照相机连线去穿透的对象集合,有几个穿透几个
let intersects = raycaster.intersectObjects(创建信息点的对象数组, true);
if (intersects.length > 0) {
    //--- 第1个被穿透,也就是纵深方向上,离你鼠标最近的对象
        console.log(intersects[0].object);
}

实现方式的不同

同一个房间,换肤切换房间

学习帖子地址 - https://juejin.cn/post/7047709128600322056#heading-1

  1. 创建一个场景,添加一个mash作为房间,仅通过更换mash的材质贴图来模拟房间的切换;
//-- 替换场景360材质图 - 开始
let texture = new THREE.TextureLoader().load('360图片链接');
let sphereMaterial = new THREE.MeshBasicMaterial({
    map: texture,
    transparent: true,
    //设置默认透明 -- 为后续切换房间场景过渡做准备,防止黑屏生硬
    opacity: 0,
});
//-- 修改房屋mash的材质
this.sphere.material = sphereMaterial;
  1. 房间场景切的换过渡
  • 因为不是真的切换房间物理位置,仅仅是切换贴图,所以仅通过改变透明度来优化
import gsap from "gsap";
...
//-- 针对房间新的360材质图,缓动透明从0 到 1
gsap.to(sphereMaterial, { transparent: true, opacity: 1, duration: 2 });
  1. 标记点的添加与移除
  • 删除标记点
this.scene.children = this.scene.children.filter(
        (item) => String(item.type) !== "Sprite"
);
  • 添加标记点
//-- 创建标记点材质
let tipTexture = new THREE.TextureLoader().load(
    require("@/assets/image/tip.png")
);
let material = new THREE.SpriteMaterial({ map: tipTexture });
//-- 添加一个带材质的
let sprite = new THREE.Sprite(material);
sprite.scale.set(xx, xx, xx);
sprite.position.set(坐标x, 坐标y, 坐标z);
sprite.content = xxxx;
this.scene.add(sprite)
  1. 鼠标滑过移除信息点,显示隐藏信息的方式
  • 通过一个div浮层,修改内部文字改变信息,修改left,top的css样式改变显示隐藏
真不同房间切换

学习帖子地址 - https://juejin.cn/post/7215268204062490679

  1. 创建一个场景,添加多个mash作为房间,有各自贴图,在不同的sence坐标位置,各自看不见;
const createRoom = (name, position, map) => {
  const geometry = new THREE.SphereGeometry(16, 256, 256);
  geometry.scale(1, 1, -1);
  const material = new THREE.MeshBasicMaterial({
    map: textLoader.load(map),
    side: THREE.DoubleSide,
  });
  const room = new THREE.Mesh(geometry, material);
  room.name = name;
  room.position.set(position.x, position.y, position.z);
  room.rotation.y = Math.PI / 2;
  scene.add(room);
  return room;
};

// 批量创建
rooms.map((item) => {
  const room = createRoom(item.key, item.position, item.map);
  return room;
});
  1. 房间场景切的换过渡,通过操作摄像机移动实现,移动过程中使用了tween库
// 点击切换场景
const handleSwitchButtonClick = async (key) => {
  const room = rooms.filter((item) => item.key === key)[0];
  if (data.camera) {
    const x = room.position.x;
    const y = room.position.y;
    const z = room.position.z;
    //-- 获取房间坐标信息,移动摄像机(缓动方式)
    Animations.animateCamera(data.camera, data.controls, { x, y, z: data.cameraZAxis }, { x, y, z }, 1600, () => {});
    data.controls.update();
  }
}
  1. 缓动库 - 缓动动画修改摄像机位置,更新摄像机,更新轨道控制器
import { TWEEN } from 'three/examples/jsm/libs/tween.module.min.js';

const Animations = {
  // 相机移动实现漫游等动画
  animateCamera: (camera, controls, newP, newT, time = 2000, callBack) => {
    const tween = new TWEEN.Tween({
      x1: camera.position.x, // 相机x
      y1: camera.position.y, // 相机y
      z1: camera.position.z, // 相机z
      x2: controls.target.x, // 控制点的中心点x
      y2: controls.target.y, // 控制点的中心点y
      z2: controls.target.z, // 控制点的中心点z
    });
    tween.to(
      {
        x1: newP.x,
        y1: newP.y,
        z1: newP.z,
        x2: newT.x,
        y2: newT.y,
        z2: newT.z,
      },
      time,
    );
    tween.onUpdate(function (object) {
      camera.position.x = object.x1;
      camera.position.y = object.y1;
      camera.position.z = object.z1;
      controls.target.x = object.x2;
      controls.target.y = object.y2;
      controls.target.z = object.z2;
      controls.update();
    });
    tween.onComplete(function () {
      controls.enabled = true;
      controls.update();
      callBack();
    });
    tween.easing(TWEEN.Easing.Cubic.InOut);
    tween.start();
  },
};
export default Animations;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容