在 React 中用 Three.js 实现 Web VR 全景看房

8,754 阅读2分钟

Next.js + Three.js 实现高性能 VR 全景看房系统

在 Web 3D 技术快速发展的今天,Three.js 已经发展得非常成熟。本文将详细介绍如何使用 Next.js 和 Three.js 构建一个高性能的 VR 全景看房系统,实现跨平台的沉浸式体验。

在线 Demo (支持 PC 和移动端) VR 看房 Demo

技术栈选择

  • Next.js: 提供 SSR 支持,优化首屏加载
  • Three.js: 使用最新版本,提供更好的性能和 API
  • TypeScript: 确保代码类型安全和可维护性

核心实现

1. 场景初始化

场景初始化是 VR 系统的基础,需要创建场景、相机和渲染器:

const init = () => {
  // 场景设置
  scene = new THREE.Scene();

  // 相机配置
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(0, 0, 0);

  // 高性能渲染器
  renderer = new THREE.WebGLRenderer({
    antialias: true,
    powerPreference: 'high-performance',
  });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
};

2. 全景环境构建

使用立方体贴图创建沉浸式环境:

const createEnvironment = () => {
  const textureLoader = new THREE.CubeTextureLoader().setPath('/static/images/vr/');

  // 加载六面贴图
  const envMap = textureLoader.load([
    'f.jpg', // 前
    'b.jpg', // 后
    'u.jpg', // 上
    'd.jpg', // 下
    'l.jpg', // 左
    'r.jpg', // 右
  ]);

  // 创建全景天空盒
  const skybox = new THREE.Mesh(
    new THREE.BoxGeometry(500, 500, 500),
    new THREE.MeshBasicMaterial({
      envMap,
      side: THREE.BackSide,
    }),
  );
  scene.add(skybox);
};

3. 相机控制系统

采用球面坐标系实现精确的视角控制:

const updateCamera = () => {
  // 限制垂直视角范围
  cameraState.lat = Math.max(-85, Math.min(85, cameraState.lat));

  // 球面坐标转换
  cameraState.phi = THREE.MathUtils.degToRad(90 - cameraState.lat);
  cameraState.theta = THREE.MathUtils.degToRad(cameraState.lon);

  // 计算目标点
  cameraState.target.x = 500 * Math.sin(cameraState.phi) * Math.cos(cameraState.theta);
  cameraState.target.y = 500 * Math.cos(cameraState.phi);
  cameraState.target.z = 500 * Math.sin(cameraState.phi) * Math.sin(cameraState.theta);

  camera.lookAt(cameraState.target);
};

4. 交互系统

实现统一的交互处理层,支持多端适配:

const setupControls = (element) => {
  if (isMobile) {
    element.addEventListener('touchstart', handleTouchStart);
    element.addEventListener('touchmove', handleTouchMove);
    element.addEventListener('touchend', handleTouchEnd);
  } else {
    element.addEventListener('pointerdown', handlePointerDown);
    element.addEventListener('pointermove', handlePointerMove);
    element.addEventListener('pointerup', handlePointerEnd);
  }
};

5. 性能优化

实现完整的资源管理和性能优化策略:

const cleanup = () => {
  // 释放渲染器资源
  renderer?.dispose();

  // 清理场景对象
  scene?.traverse((object) => {
    if (object instanceof THREE.Mesh) {
      object.geometry?.dispose();
      object.material?.dispose();
    }
  });

  // 取消动画帧
  cancelAnimationFrame(animationFrameId);

  // 移除事件监听
  removeEventListeners();
};

技术亮点

  1. 状态管理

    • 统一的相机状态管理
    • 可预测的视角控制
    • 平滑的状态过渡
  2. 事件系统

    • 统一的事件处理机制
    • 触摸和鼠标事件适配
    • 防抖和节流优化
  3. 性能优化

    • 自动资源释放
    • 设备像素比优化
    • 按需渲染策略
  4. 用户体验

    • 平滑的动画效果
    • 直观的交互响应
    • 沉浸式体验

最佳实践

  1. 代码组织

    • 模块化设计
    • 清晰的职责分离
    • 可测试的架构
  2. 资源管理

    • 自动内存回收
    • GPU 资源优化
    • 生命周期管理
  3. 错误处理

    • 优雅的降级策略
    • 完整的错误捕获
    • 用户友好的提示

项目源码

完整的项目代码已开源在 GitHub:nextjs-demo

总结

本项目展示了如何在 Next.js 框架下构建专业级的 VR 全景系统。通过合理的架构设计和优化策略,实现了流畅的用户体验和高效的资源管理。这个实现不仅适用于房产展示,还可以扩展到虚拟展厅、景点导览等多个领域。

更多 Three.js 和 Next.js 的进阶用法,请参考: