Threejs实现 3D 看房效果

要实现一个 3D 看房效果,可以使用 Three.js 创建一个虚拟的 3D 场景,并通过加载全景图片或 3D 模型来模拟房间的外观。以下是一个完整的实现方案,结合代码逐步讲解如何实现这一功能。


实现步骤

  1. 创建基础场景和相机
    使用 Three.js 创建一个基础的 3D 场景,并设置透视相机。
  2. 加载全景图片
    使用立方体贴图(CubeTexture)加载六张全景图片(上下左右前后),形成一个球形环境。
  3. 添加交互控制
    使用 OrbitControls 或类似库,允许用户通过鼠标拖动、缩放等方式查看房间。
  4. 优化渲染性能
    确保场景的渲染性能良好,并适配不同分辨率的设备。

示例代码

以下是实现 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: 启用阻尼效果,使旋转更平滑。
    • minDistancemaxDistance: 限制用户与场景的距离。
    • 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 倍(负值表示反向缩放)。

作用

  1. 调整几何体大小
    通过缩放几何体,可以动态改变物体的尺寸。这对创建不同大小的物体或响应用户交互非常有用。
  2. 反向缩放
    Z 轴方向使用了负值(-10),这不仅会缩放几何体,还会反转 Z 轴的方向。这种操作通常用于镜像效果或调整模型的方向。

注意事项

  1. 全景图片要求
    • 六张图片需要是无缝拼接的,确保在立方体的每个面之间没有明显的接缝。
    • 图片分辨率应足够高,以保证清晰度,但也不能过大,以免影响加载速度。
  2. 性能优化
    • 在移动端设备上,降低渲染分辨率或减少贴图质量以提高性能。
    • 使用 renderer.setPixelRatio(window.devicePixelRatio) 确保在高分辨率屏幕上显示清晰。
  3. 支持更多功能
    • 热点区域:可以在房间中添加可点击的热点区域,用于展示更多信息或切换视角。
    • 动态光照:如果需要更真实的场景,可以添加光源和阴影效果。
  4. 直接修改几何体
    geometry.scale() 直接修改了几何体的数据,因此会影响所有使用该几何体的物体。如果需要单独缩放某个物体,建议使用 object.scale.set(),而不是直接修改几何体。
  5. 性能影响
    修改几何体可能会影响渲染性能,尤其是在复杂场景中。如果频繁调整几何体,可能会导致性能下降。
  6. 负值缩放的影响
    使用负值缩放可能会导致法线方向反转,从而影响光照和阴影效果。如果发现光照异常,可以通过重新计算法线来修复:

相关推荐
谁在黄金彼岸2 小时前
Threejs实现物理运动模拟
前端
kyriewen2 小时前
原型与原型链:JavaScript 的“家族关系”大揭秘
前端·javascript·ecmascript 6
谁在黄金彼岸2 小时前
Flutter应用在Windows 8上正常运行
前端
谁在黄金彼岸2 小时前
Vue项目中引入three.js并加载GLB模型流程与常见问题
前端
谁在黄金彼岸2 小时前
开发Chrome_Edge插件基本流程
前端
滴滴答答哒2 小时前
layui表格头部按钮 加入下拉选项
前端·javascript·layui
Cache技术分享2 小时前
359. Java IO API - 路径比较与处理
前端·后端
Jackson__2 小时前
OpenSpec:AI 写代码,先立规矩再动手
前端·ai编程
乌索普-2 小时前
基于vue2的简易购物车
开发语言·前端·javascript