要实现一个 3D 看房效果,可以使用 Three.js 创建一个虚拟的 3D 场景,并通过加载全景图片或 3D 模型来模拟房间的外观。以下是一个完整的实现方案,结合代码逐步讲解如何实现这一功能。
实现步骤
- 创建基础场景和相机
使用 Three.js 创建一个基础的 3D 场景,并设置透视相机。 - 加载全景图片
使用立方体贴图(CubeTexture)加载六张全景图片(上下左右前后),形成一个球形环境。 - 添加交互控制
使用OrbitControls或类似库,允许用户通过鼠标拖动、缩放等方式查看房间。 - 优化渲染性能
确保场景的渲染性能良好,并适配不同分辨率的设备。
示例代码
以下是实现 3D 看房效果的完整代码示例:
typescript
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
// Three.js 相关变量声明
let scene: THREE.Scene
let camera: THREE.PerspectiveCamera
let renderer: THREE.WebGLRenderer
let controls: OrbitControls
const canvas = ref<HTMLCanvasElement>()
onMounted(() => {
initScene()
animate()
})
function initScene() {
if (!canvas.value) return
// 获取画布尺寸
const width = canvas.value.clientWidth
const height = canvas.value.clientHeight
// 创建场景
scene = new THREE.Scene()
// 创建透视相机
camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
camera.position.set(0, 0, 0)
// 创建 WebGL 渲染器
renderer = new THREE.WebGLRenderer({ canvas: canvas.value, antialias: true })
renderer.setSize(width, height)
renderer.setPixelRatio(window.devicePixelRatio)
// 加载全景图片
const loader = new THREE.CubeTextureLoader()
const texture = loader.load([
'/src/assets/img/right.jpg', // 右
'/src/assets/img/left.jpg', // 左
'/src/assets/img/top.jpg', // 上
'/src/assets/img/bottom.jpg',// 下
'/src/assets/img/front.jpg', // 前
'/src/assets/img/back.jpg', // 后
])
scene.background = texture
// 添加轨道控制器
controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
controls.dampingFactor = 0.05
controls.minDistance = 1
controls.maxDistance = 10
controls.enablePan = false // 禁用平移
}
function animate() {
requestAnimationFrame(animate)
controls.update() // 更新控制器
renderer.render(scene, camera)
}
</script>
<template>
<div>
<canvas ref="canvas" class="canvas"></canvas>
</div>
</template>
<style scoped>
.canvas {
display: block;
width: 100%;
height: 100vh; /* 占满整个视口高度 */
}
</style>
代码说明
1. 创建基础场景
- 使用
THREE.Scene创建一个空的 3D 场景。 - 设置透视相机
THREE.PerspectiveCamera,模拟人眼的视角。 - 使用
THREE.WebGLRenderer渲染场景,并将其绑定到 HTML 的<canvas>元素上。
2. 加载全景图片
- 使用
THREE.CubeTextureLoader加载六张图片(上下左右前后),这些图片共同构成了一个立方体贴图。 - 将加载的贴图设置为场景的背景 (
scene.background),从而形成一个球形的全景环境。
3. 添加交互控制
- 使用
OrbitControls提供交互功能,允许用户通过鼠标拖动旋转视角,或通过滚轮缩放。 - 配置控制器参数:
enableDamping: 启用阻尼效果,使旋转更平滑。minDistance和maxDistance: 限制用户与场景的距离。enablePan: 禁用平移,避免用户移动到房间外部。
4. 动画循环
- 使用
requestAnimationFrame创建一个动画循环,持续更新控制器并重新渲染场景。
5.几何体的缩放操作
javascript
cube1.geometry.scale(10, 10, -10)
cube1.geometry
这是cube1的几何体对象。geometry是 Three.js 中用于定义物体形状的属性。.scale(x, y, z)
scale方法用于对几何体进行缩放。它接受三个参数:x: 在 X 轴方向上的缩放比例。y: 在 Y 轴方向上的缩放比例。z: 在 Z 轴方向上的缩放比例。
在这段代码中:
-
X 轴方向放大 10 倍。
-
Y 轴方向放大 10 倍。
-
Z 轴方向缩小 10 倍(负值表示反向缩放)。
作用
- 调整几何体大小
通过缩放几何体,可以动态改变物体的尺寸。这对创建不同大小的物体或响应用户交互非常有用。 - 反向缩放
Z 轴方向使用了负值(-10),这不仅会缩放几何体,还会反转 Z 轴的方向。这种操作通常用于镜像效果或调整模型的方向。
注意事项
- 全景图片要求
- 六张图片需要是无缝拼接的,确保在立方体的每个面之间没有明显的接缝。
- 图片分辨率应足够高,以保证清晰度,但也不能过大,以免影响加载速度。
- 性能优化
- 在移动端设备上,降低渲染分辨率或减少贴图质量以提高性能。
- 使用
renderer.setPixelRatio(window.devicePixelRatio)确保在高分辨率屏幕上显示清晰。
- 支持更多功能
- 热点区域:可以在房间中添加可点击的热点区域,用于展示更多信息或切换视角。
- 动态光照:如果需要更真实的场景,可以添加光源和阴影效果。
- 直接修改几何体
geometry.scale()直接修改了几何体的数据,因此会影响所有使用该几何体的物体。如果需要单独缩放某个物体,建议使用object.scale.set(),而不是直接修改几何体。 - 性能影响
修改几何体可能会影响渲染性能,尤其是在复杂场景中。如果频繁调整几何体,可能会导致性能下降。 - 负值缩放的影响
使用负值缩放可能会导致法线方向反转,从而影响光照和阴影效果。如果发现光照异常,可以通过重新计算法线来修复: