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: 启用阻尼效果,使旋转更平滑。
    • 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 倍(负值表示反向缩放)。

作用

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

注意事项

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

相关推荐
IT_陈寒6 分钟前
Redis内存暴涨,没想到是AOF重写捣的鬼
前端·人工智能·后端
ikoala6 分钟前
让 Codex 自己查账:一个省 token 的小技巧
前端·后端·ai编程
ikoala17 分钟前
AI 写页面像说明书,修 Bug 像贴膏药?把这两句话写进 AGENTS.md
前端·javascript·ai编程
去伪存真3 小时前
AI Agent Harness 深度测评与技术选型实战
前端·agent
FRing035 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
疯华整猫8 小时前
被杀掉之后:我把 Android 的「唤起 + 常驻」重做了一遍
前端·面试·架构
IT_陈寒10 小时前
Java开发实战:从入门到精通
前端·人工智能·后端
风骏时光牛马11 小时前
生成一个AI转岗经历标题,只需要一个标题,不需要其他的任何文本。
前端
Csvn20 小时前
Monorepo
前端
Csvn20 小时前
流水线
前端