Three.js使用全景图做360°背景贴图

一、准备工作

对于一张全景图,一般都具备上下左右前后6个方向,所以准备工作就是需要准备六张图片,包含六个方位(类比正方体),最好使用【全景图】来进行裁切,得到完整且流畅过度的六张图片,这里我使用的是【PTGui】软件进行全景图裁切
官网下载地址:PTGui
(https://ptgui.com/download.html?ps=main)
具体使用流程如下:

  1. 打开一张全景图
    Three.js使用全景图做360°背景贴图_第1张图片
  2. 选择顶部的Tools
    Three.js使用全景图做360°背景贴图_第2张图片
  3. 设置导出格式,点击【Convert】即可导出6张图片Three.js使用全景图做360°背景贴图_第3张图片

二、代码实现

这里我使用的是 Vue3 + vite + three.js 脚手架搭建的项目

<template>
  <div id="my-three" ref="screenDom"></div>
</template>

<script setup>
import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import {ref, onMounted} from "vue"
import px from '../assets/环境贴图/01/px.jpg'
import nx from '../assets/环境贴图/01/nx.jpg'
import py from '../assets/环境贴图/01/py.jpg'
import ny from '../assets/环境贴图/01/ny.jpg'
import pz from '../assets/环境贴图/01/pz.jpg'
import nz from '../assets/环境贴图/01/nz.jpg'
import { DoubleSide } from 'three'
// console.log(THREE)

let screenDom = ref(null)

onMounted(() => {
  // 1. 创建场景
  const scene = new THREE.Scene()

  // 2. 创建相机
  const camera = new THREE.PerspectiveCamera(75, screenDom.value.clientWidth / screenDom.value.clientHeight, 0.1, 1000)

  // 3. 设置相机位置
  camera.position.set(5, 5, 15)
  scene.add(camera)

  // 设置cube纹理加载器
  const cubeTextureLoader = new THREE.CubeTextureLoader()
  const envMapTexture = cubeTextureLoader.load([px, nx, py, ny, pz, nz])

  // 4. 创建几何体
  const sphereGeometry = new THREE.SphereGeometry(2, 32, 32)
  const material = new THREE.MeshStandardMaterial({
    metalness: 1,
    roughness: 0.1, 
    envMap: envMapTexture
  })       // 材质
  const cube = new THREE.Mesh(sphereGeometry, material)     // 根据缓冲几何体和材质创建物体

  scene.add(cube)     // 将几何体添加到场景中

  // 给场景添加背景
  scene.background = envMapTexture
  // 给场景所有物体添加默认的环境贴图(类似于单独给材质添加环境贴图   envMap: envMapTexture  )
  // scene.environment = envMapTexture


  // 添加环境光
  // 第一个参数是环境光的【颜色】,第二个是【光照强度】
  const light = new THREE.AmbientLight(0xffffff, 0.5)
  scene.add(light)

  // 5. 初始化渲染器
  const renderer = new THREE.WebGLRenderer()

  // 设置渲染尺寸大小
  renderer.setSize(screenDom.value.clientWidth, screenDom.value.clientHeight)
  // console.log(renderer)
  // 将webgl渲染的canvas内容添加到指定位置
  screenDom.value.appendChild(renderer.domElement)

  // 创建轨道控制器
  const controls = new OrbitControls(camera, renderer.domElement)

  // 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用 update()
  controls.enableDamping = true

  // 添加坐标轴辅助器
  // const axesHelper = new THREE.AxesHelper(6)
  // scene.add(axesHelper)

  // 双击屏幕进入或退出全屏
  window.addEventListener('dblclick', () => {
    document.fullscreenElement ? document.exitFullscreen() : renderer.domElement.requestFullscreen()
  })

  function render(time) {
    controls.update()
    // 使用渲染器,通过相机将场景渲染进来
    renderer.render(scene, camera)

    // 渲染下一帧的时候就会调用render函数
    requestAnimationFrame(render)
  }

  render()

  // 监听画面变化,更新渲染画面
  window.addEventListener('resize', () => {
    // 更新摄像头
    camera.aspect = screenDom.value.clientWidth / screenDom.value.clientHeight

    // 更新摄像头的投影矩阵
    camera.updateProjectionMatrix()

    // 更新渲染器
    renderer.setSize(screenDom.value.clientWidth, screenDom.value.clientHeight)

    // 设置渲染器的像素比
    renderer.setPixelRatio(window.devicePixelRatio)
  })
})


</script>

<style scoped>

#my-three {
  width: 100%;
  height: 100%;
}
</style>

三、实现效果

Three.js使用全景图做360°背景贴图_第4张图片

你可能感兴趣的:(vue.js,javascript)