使用three.js实现VR看房,超简单!

发布于:2024-05-02 ⋅ 阅读:(24) ⋅ 点赞:(0)

效果

先看效果:

实现

创建渲染器、场景,设置相机

const canvas = document.querySelector('#container');
const renderer = new THREE.WebGLRenderer({ canvas });

const fov = 40;
const aspect = 2;
const near = 0.1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 50, 0);
camera.up.set(0, 0, 1);

const scene = new THREE.Scene();

此时只有一块黑色的背景:

使用TextureLoader加载纹理贴图

const materials = [];
const textureLeft = new THREE.TextureLoader().load('./p1.jpeg');
// 校准贴图位置摆放
textureLeft.center.set(0.5, 0.5)// 表示在中心点位置旋转
textureLeft.rotation = - Math.PI / 2;
materials.push(new THREE.MeshBasicMaterial({ map: textureLeft }));

const textureRight = new THREE.TextureLoader().load('./p2.jpeg');
textureRight.center.set(0.5, 0.5)
textureRight.rotation = Math.PI / 2;
materials.push(new THREE.MeshBasicMaterial({ map: textureRight }));

const textureTop = new THREE.TextureLoader().load('./p3.jpeg');
materials.push(new THREE.MeshBasicMaterial({ map: textureTop }));

const textureBottom = new THREE.TextureLoader().load('./p4.jpeg');
textureBottom.center.set(0.5, 0.5)
textureBottom.rotation = Math.PI;
materials.push(new THREE.MeshBasicMaterial({ map: textureBottom }));

const textureFront = new THREE.TextureLoader().load('./p5.jpeg');
materials.push(new THREE.MeshBasicMaterial({ map: textureFront }));
textureFront.center.set(0.5, 0.5)
textureFront.rotation = Math.PI;

const textureBack = new THREE.TextureLoader().load('./p6.jpeg');
materials.push(new THREE.MeshBasicMaterial({ map: textureBack }));

使用纹理创建立方体

const box = new THREE.Mesh(new THREE.BoxGeometry(60, 60, 60), materials);

将立方体添加到场景中

scene.add(box);

此时得到一个立方体:

将立方体贴图向内翻转

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

效果基本出现了:

将立方体调大一些(占满整个背景),VR看房的效果就有了。

添加轨道控制器

为了让你使用鼠标或触摸板自由查看自己的房间,你需要添加轨道控制器,它可以让你控制相机围绕立方体旋转、缩放等。

new OrbitControls(camera, renderer.domElement);

以上就是使用three.js实现VR看房的全部代码啦,赶快去试试吧~

(附)完整代码

import React, { useEffect } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const Index = () => {
  useEffect(() => {
    const canvas = document.querySelector('#container');
    const renderer = new THREE.WebGLRenderer({ canvas });

    const fov = 40;
    const aspect = 2;
    const near = 0.1;
    const far = 1000;
    const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    camera.position.set(0, 50, 0);
    camera.up.set(0, 0, 1);

    const scene = new THREE.Scene();

    {
      const materials = [];
      const textureLeft = new THREE.TextureLoader().load('./p1.jpeg');
      textureLeft.center.set(0.5, 0.5)
      textureLeft.rotation = - Math.PI / 2;
      materials.push(new THREE.MeshBasicMaterial({ map: textureLeft }));

      const textureRight = new THREE.TextureLoader().load('./p2.jpeg');
      textureRight.center.set(0.5, 0.5)
      textureRight.rotation = Math.PI / 2;
      materials.push(new THREE.MeshBasicMaterial({ map: textureRight }));

      const textureTop = new THREE.TextureLoader().load('./p3.jpeg');
      materials.push(new THREE.MeshBasicMaterial({ map: textureTop }));

      const textureBottom = new THREE.TextureLoader().load('./p4.jpeg');
      textureBottom.center.set(0.5, 0.5)
      textureBottom.rotation = Math.PI;
      materials.push(new THREE.MeshBasicMaterial({ map: textureBottom }));

      const textureFront = new THREE.TextureLoader().load('./p5.jpeg');
      materials.push(new THREE.MeshBasicMaterial({ map: textureFront }));
      textureFront.center.set(0.5, 0.5)
      textureFront.rotation = Math.PI;

      const textureBack = new THREE.TextureLoader().load('./p6.jpeg');
      materials.push(new THREE.MeshBasicMaterial({ map: textureBack }));

      const box = new THREE.Mesh(new THREE.BoxGeometry(60, 60, 60), materials);
      scene.add(box);

      box.geometry.scale(1, 1, -1);
      new OrbitControls(camera, renderer.domElement);
    }

    function render() {
      renderer.render(scene, camera);
      requestAnimationFrame(render);
    }

    requestAnimationFrame(render);
  }, []);

  return (
    <canvas id="container" width="1500px" height="800px"></canvas>
  );
};

export default Index;