Threejs案例
Car

沉浸式3D汽车展示项目 - React Three.js 炫酷实现

介绍一个基于 React Three.js 构建的高质量3D汽车展示项目,通过现代Web技术呈现出令人惊艳的视觉效果。

项目融合了逼真的光影渲染、动态特效和交互式操作,为用户带来如同置身于未来汽车展厅的沉浸式体验。

核心功能特色

1. 3D汽车模型展示

  • 采用高精度 GLB 格式3D模型(马自达RX7跑车)
  • 支持 DRACO 压缩技术,显著减少模型文件大小
  • 实现车轮动态旋转动画效果
  • 智能加载进度显示,提升用户体验

2. 酷炫视觉特效

  • 动态光环系统:14个彩色圆环循环运动,营造科技感氛围
  • 粒子盒子特效:100个随机颜色方块在场景中飘动
  • 反射地面:高质量地面反射,增强画面层次感
  • 浮动网格:透明网格纹理营造未来科技感

3. 专业级后期处理

  • 辉光效果(Bloom):模拟真实光线溢出
  • 色差特效(ChromaticAberration):增添电影级质感
  • 景深效果(DepthOfField):可选择性模糊背景

4. 智能灯光系统

  • 双色调聚光灯:粉紫色和蓝色灯光营造氛围
  • 实时阴影投射:所有物体支持动态阴影
  • 环境映射:利用CubeCamera实现实时环境反射

技术架构解析

核心技术栈

{
  "react": "^18.0.0",           // React框架
  "@react-three/fiber": "8.0.11",    // Three.js的React封装
  "@react-three/drei": "9.4.2",      // Three.js辅助组件库
  "@react-three/postprocessing": "2.3.2",  // 后期处理效果
  "three": "0.139.2"            // 核心3D引擎
}

项目结构

src/
├── App.js          # 主应用组件,场景配置
├── Car.js          # 汽车3D模型组件
├── Ground.js       # 反射地面组件
├── Rings.js        # 动态光环特效
├── Boxes.js        # 粒子方块系统
├── FloatingGrid.js # 浮动网格背景
└── style.css       # 样式文件

关键代码实现

1. 汽车模型加载核心逻辑

// Car.js:10-39
export function Car() {
  const gltf = useLoader(
    GLTFLoader,
    process.env.PUBLIC_URL + "models/car/rx7.glb",
    (loader) => {
      const dracoLoader = new DRACOLoader();
      dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.6/");
      
      loader.setDRACOLoader(dracoLoader);
      loader.load(
        process.env.PUBLIC_URL + "models/car/rx7.glb",
        () => {
          console.log("模型成功加载!");
          document.querySelector('.loading').style.display = 'none'
        },
        // 加载进度回调
        (xhr) => {
          const percentLoaded = (xhr.loaded / xhr.total) * 100;
          console.log(`加载进度: ${percentLoaded}%`);
        }
      );
    }
  );
}

技术要点

  • 使用 useLoader Hook异步加载3D模型
  • 集成DRACO解压缩器优化加载性能
  • 实现加载进度追踪和错误处理

2. 动态光环特效系统

// Rings.js:8-30
useFrame((state, delta) => {
  let elapsed = state.clock.getElapsedTime();
  
  for (let i = 0; i < itemsRef.current.length; i++) {
    let mesh = itemsRef.current[i];
    let z = (i - 7) * 4 + ((elapsed * 0.4) % 4) * 2;
    let dist = Math.abs(z);
    
    mesh.position.set(0, 0, -z);
    mesh.scale.set(1 - dist * 0.04, 1 - dist * 0.04, 1 - dist * 0.04);
    
    // 动态颜色变化
    if (i % 2 == 1) {
      mesh.material.emissive = new Color(6, 0.15, 0.7).multiplyScalar(colorScale);
    } else {
      mesh.material.emissive = new Color(0.1, 0.7, 3).multiplyScalar(colorScale);
    }
  }
});

技术要点

  • 使用 useFrame 实现每帧动画更新
  • 基于距离的缩放和颜色计算
  • 交替颜色模式营造视觉节奏感

3. 高质量反射地面

// Ground.js:30-55
<mesh rotation-x={-Math.PI * 0.5} castShadow receiveShadow>
  <planeGeometry args={[30, 30]} />
  <MeshReflectorMaterial
    envMapIntensity={0}
    normalMap={normal}
    normalScale={[0.15, 0.15]}
    roughnessMap={roughness}
    color={[0.015, 0.015, 0.015]}
    blur={[1000, 400]}
    mixBlur={30}
    mixStrength={80}
    resolution={1024}
    mirror={0}
  />
</mesh>

技术要点

  • 使用 MeshReflectorMaterial 实现实时反射
  • 法线贴图和粗糙度贴图增强真实感
  • 精确的模糊和混合参数调节

交互体验

相机控制

// App.js:38-39
<OrbitControls target={[0, 0.35, 0]} maxPolarAngle={1.45}/>
<PerspectiveCamera makeDefault fov={50} position={[3, 2, 5]}/>
  • 鼠标拖拽:360度环绕观看汽车
  • 滚轮缩放:自由调节观察距离
  • 智能限制:防止相机穿透地面

🔧 快速启动

npm install
npm start

项目将在 http://localhost:3000 启动


源码

https://github.com/n1k02/three-js-projects/tree/main/car-show-react-three (opens in a new tab)