前言
web3D图形学,元宇宙,数字孪生,作为一名前端开发者,不可不学炫酷技能,引领下一个10年。VR在线看房、看车、旅游等,是当下热门技术,Three.js简单实现一个VR看房,话不多说,直接贴源码:gitee.com/weiweiwucod...
项目启动后,效果路径:http://localhost:5173/geometry/T2
效果图
技术栈
- three.js v0.169.0
- vue v3.5.10
- vite v5.4.8
- node v20.17.0
- dat.gui v0.7.9
全景图切割工具:matheowis.github.io/HDRI-to-Cub...
实现原理
用three.js实现一个正方体,然后在正方体的六个面贴上前后左右上下六张图片,camera放在正方体内,可模拟实现VR
实现步骤
分解动作,一步一动,逐步完成,相信你在阅读的时候也可以跟着一起敲击键盘来完成,passion
- 创建容器: 在开始使用three.js之前,你需要一个地方来显示它。vue技术栈,需要在template里创建一个div容器,用来挂载渲染后的cavans
js
<template>
<div ref="Cavans"></div>
</template>
- 创建场景:
js
// 创建一个场景
const scene = new THREE.Scene()
- 添加相机: 这里我们使用PerspectiveCamera,透视投影相机,它有四个参数视野角度(FOV)、长宽比(aspect ratio)、近截面(near)、远截面(far)
js
const camera = new THREE.PerspectiveCamera( 75, document.body.clientWidth / document.body.clientHeight, 0.1, 100 )
camera.lookAt(scene.position)
scene.add(camera)
- 渲染器: 接下来是渲染器,这里是施展魔法的地方。我们在这里用的WebGLRenderer渲染器,暂不考虑不支持WebGL的情况
js
const renderer = new THREE.WebGLRenderer(})
renderer.render( scene, camera );
- 挂载: onMounted 注意vue的生命周期函数
js
const Cavans = ref(null)
onMounted(()=>{
// 挂载
Cavans.value.appendChild(renderer.domElement)
})
- 创建几何体--立方体: BoxGeometry
js
// 创建一个立方体
const geometry = new THREE.BoxGeometry( 10, 10, 10 )
- 六张vr分割的图片
js
const vrImgList = [px, nx, py, ny, pz, nz]
const faces = []
for(let i = 0; i < geometry.groups.length; i++){
const vrTexture = new THREE.TextureLoader().load(`${vrImgList[i]}`)
const material = new THREE.MeshBasicMaterial({
map: vrTexture,
// wireframe: true
})
faces.push(material)
}
// Mesh 网格 网格包含一个几何体 geometry 以及作用在此几何体上的材质 material
const cube = new THREE.Mesh( geometry, faces );
// 调用 scene.add(),物体将会被添加到 (0,0,0) 坐标
scene.add(cube)
cube.geometry.scale(-5, 5, 5);
camera.position.x = 5
- 控制器
js
const controls = new OrbitControls(camera, renderer.domElement)
// 将其设置为true以启用阻尼(惯性),这将给控制器带来重量感。默认值为false。 请注意,如果该值被启用,你将必须在你的动画循环里调用update()
controls.enableDamping = true
// 当.enableDamping设置为true的时候,阻尼惯性有多大。 Default is 0.05. 请注意,要使得这一值生效,你必须在你的动画循环里调用 update()
controls.dampingFactor = 1
const animate = () => {
// 浏览器API
requestAnimationFrame( animate );
controls.update() // 更新轨道控制器
stats.update() // 更新监控帧数
renderer.render( scene, camera );
}
animate();
- 优化:
js
// 渲染器优化 抗锯齿antialias
const renderer = new THREE.WebGLRenderer({
antialias: true, // 抗锯齿
})
// 优化 设置像素比
renderer.setPixelRatio(window.devicePixelRatio || 1)
// 渲染器的尺寸
renderer.setSize(document.body.clientWidth, document.body.clientHeight)
// 自适应
resizeHandler(renderer, camera)
js
// 自适应
const resizeHandler = (renderer: { setSize: (arg0: number, arg1: number) => void; },camera: { aspect: number; updateProjectionMatrix: () => void; }) => {
window.addEventListener('resize', ()=>{
// 更新相机
camera.aspect = document.body.clientWidth / document.body.clientHeight
camera.updateProjectionMatrix() // 请注意,在大多数属性发生改变之后,你将需要调用.updateProjectionMatrix来使得这些改变生效
// 更新渲染器大小
renderer.setSize(document.body.clientWidth, document.body.clientHeight)
})
}
*写到这里基本完事了,目前threejs持续学习中,有错误和的不足地方欢迎指正和交流学习,代码部分会持续更新,完整代码移步:gitee.com/weiweiwucod... *
路虽远,行则将至~~