一、准备工作
对于一张全景图,一般都具备上下左右前后6个方向,所以准备工作就是需要准备六张图片,包含六个方位(类比正方体),最好使用【全景图】来进行裁切,得到完整且流畅过度的六张图片,这里我使用的是【PTGui】软件进行全景图裁切
官网下载地址:PTGui
(https://ptgui.com/download.html?ps=main)
具体使用流程如下:
- 打开一张全景图
- 选择顶部的Tools
- 设置导出格式,点击【Convert】即可导出6张图片
二、代码实现
这里我使用的是 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>